Page Menu
Home
Xreate
Search
Configure Global Search
Log In
Docs
Questions
Repository
Issues
Patches
Internal API
Files
F4820966
LispInterpreter.java
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Mon, Aug 24, 10:05 AM
Size
9 KB
Mime Type
text/plain
Expires
Wed, Aug 26, 10:05 AM (1 d, 22 h)
Engine
blob
Format
Raw Data
Handle
283219
Attached To
rXR Xreate
LispInterpreter.java
View Options
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package
org.xreate.grammatic.lisp
;
import
com.google.common.collect.ImmutableMap
;
import
com.google.common.collect.Lists
;
import
com.google.common.collect.Maps
;
import
java.io.IOException
;
import
java.lang.reflect.Method
;
import
java.math.BigInteger
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.Map
;
import
org.antlr.runtime.*
;
import
org.jllvm.*
;
import
org.jllvm.bindings.*
;
import
org.xreate.TestRunner2
;
/**
*
* @author pgess
*/
public
class
LispInterpreter
{
static
Map
<
String
,
String
>
htable
;
static
Map
<
String
,
LLVMType
>
ttable
;
public
Map
<
String
,
String
>
opcodes
=
Maps
.
newLinkedHashMap
();
public
Map
<
String
,
LLVMFunction
>
functions
=
Maps
.
newLinkedHashMap
();
protected
LLVMInstructionBuilder
builder
=
new
LLVMInstructionBuilder
();
protected
LLVMModule
module
=
new
LLVMModule
(
"script"
);
//"/private/prg/code/xreate/scripts/opcode.li"
public
void
run
(
String
filename
)
throws
IOException
,
RecognitionException
,
Exception
{
ANTLRStringStream
in
=
new
ANTLRFileStream
(
filename
);
Lexer
l
=
new
LispLexer
(
in
);
CommonTokenStream
tokens
=
new
CommonTokenStream
(
l
);
LispParser
p
=
new
LispParser
(
tokens
);
while
(
true
){
ASTLispNode
node
=
p
.
statement
(
null
);
handle
(
node
);
}
}
public
void
opcodeDef
(
ASTLispNode
node
){
ArrayList
<
ASTLispNode
>
params
=
node
.
parameters
;
opcodes
.
put
(
params
.
get
(
0
).
caption
,
params
.
get
(
1
).
caption
);
}
public
void
functionDef
(
ASTLispNode
node
)
throws
Exception
{
ArrayList
<
ASTLispNode
>
nodes_vars
=
node
.
get
(
"vars-list"
).
parameters
;
int
nsize
=
nodes_vars
.
size
();
LLVMType
[]
arg_types
=
new
LLVMType
[
nsize
];
for
(
int
i
=
0
;
i
<
nsize
;
i
++){
String
type_caption
=
nodes_vars
.
get
(
i
).
get
(
"type"
).
parameters
.
get
(
0
).
caption
;
arg_types
[
i
]
=
ttable
.
get
(
type_caption
);
}
LLVMType
ret_type
=
ttable
.
get
(
node
.
get
(
"return"
).
get
(
"type"
).
parameters
.
get
(
0
).
caption
);
String
func_name
=
node
.
get
(
"name"
).
parameters
.
get
(
0
).
caption
;
LLVMFunctionType
func_type
=
new
LLVMFunctionType
(
ret_type
,
arg_types
,
false
);
LLVMFunction
func
=
new
LLVMFunction
(
module
,
func_name
,
func_type
);
LLVMBasicBlock
entry
=
func
.
appendBasicBlock
(
"entry"
);
builder
.
positionBuilderAtEnd
(
entry
);
LLVMValue
[]
values
=
func
.
getParameters
();
String
[]
vars
=
new
NodeFunctionVarsList
(
node
.
get
(
"vars-list"
)).
getVarNames
();
LLVMValue
func_body
=
new
Evaluator
(
vars
,
values
).
eval
(
node
.
get
(
"body"
).
parameters
.
get
(
0
));
new
LLVMReturnInstruction
(
builder
,
func_body
);
SWIGTYPE_p_p_char
outerrs
=
ExecutionEngine
.
new_StringArray
(
1
);
int
x
=
Analysis
.
LLVMVerifyFunction
(
func
.
getInstance
(),
LLVMVerifierFailureAction
.
LLVMReturnStatusAction
);
x
=
Analysis
.
LLVMVerifyModule
(
module
.
getInstance
(),
LLVMVerifierFailureAction
.
LLVMReturnStatusAction
,
outerrs
);
ExecutionEngine
.
delete_StringArray
(
outerrs
);
outerrs
=
null
;
functions
.
put
(
func_name
,
func
);
}
public
int
main
(
ASTLispNode
node
)
throws
Exception
{
String
func_main_name
=
node
.
parameters
.
get
(
0
).
caption
;
LLVMFunction
func_main
=
functions
.
get
(
func_main_name
);
if
(
null
==
func_main
){
throw
new
Exception
(
"Main function not found!"
);
}
boolean
isNative
=
LLVMTargetData
.
initializeNativeTarget
();
LispJITRunnerWrapper
program
=
new
LispJITRunnerWrapper
(
module
);
LLVMGenericValue
resultRef
=
program
.
runFunction
(
func_main
,
new
LLVMGenericValue
[
0
]);
BigInteger
resultBig
=
ExecutionEngine
.
LLVMGenericValueToInt
(
resultRef
.
getInstance
(),
0
);
int
result
=
resultBig
.
intValue
();
return
result
;
/*
TestRunner2 runner = new TestRunner2();
runner.setModule(module);
runner.runBody(func_main);
return 0;
*
*/
}
public
Object
handle
(
ASTLispNode
node
)
throws
Exception
{
String
caption
=
node
.
caption
;
String
method
=
htable
.
get
(
caption
);
if
(
method
==
null
)
{
throw
new
Exception
();
}
Method
invoker
=
this
.
getClass
().
getDeclaredMethod
(
method
,
ASTLispNode
.
class
);
return
invoker
.
invoke
(
this
,
node
);
}
public
LispInterpreter
(){
}
static
{
/*
* Handler table хранит информацию о соответствии метода и команды
*/
htable
=
new
ImmutableMap
.
Builder
<
String
,
String
>()
.
put
(
"opcode"
,
"opcodeDef"
)
.
put
(
"function"
,
"functionDef"
)
.
put
(
"calculate"
,
"calculate"
)
.
put
(
"main"
,
"main"
)
.
build
();
/*
* Types Table - хранит информацию о соответствии типов
*/
ttable
=
new
ImmutableMap
.
Builder
<
String
,
LLVMType
>()
.
put
(
"i32"
,
LLVMIntegerType
.
i32
)
.
put
(
"i16"
,
LLVMIntegerType
.
i16
)
.
put
(
"i8"
,
LLVMIntegerType
.
i8
)
.
build
();
}
class
Evaluator
{
Map
<
String
,
LLVMValue
>
arguments
;
public
Evaluator
(
String
[]
names
,
LLVMValue
[]
values
)
{
int
size
=
names
.
length
;
arguments
=
Maps
.
newHashMapWithExpectedSize
(
size
);
for
(
int
i
=
0
;
i
<
size
;
i
++){
arguments
.
put
(
names
[
i
],
values
[
i
]);
}
}
public
LLVMValue
LLVMAddInstruction
(
ASTLispNode
node
)
throws
Exception
{
LLVMValue
arg1
=
eval
(
node
.
parameters
.
get
(
0
));
LLVMValue
arg2
=
eval
(
node
.
parameters
.
get
(
1
));
return
new
LLVMAddInstruction
(
builder
,
arg1
,
arg2
,
false
,
"add"
);
}
public
LLVMValue
LLVMDivideInstruction
(
ASTLispNode
node
)
throws
Exception
{
LLVMValue
arg1
=
eval
(
node
.
parameters
.
get
(
0
));
LLVMValue
arg2
=
eval
(
node
.
parameters
.
get
(
1
));
return
new
LLVMDivideInstruction
(
builder
,
arg1
,
arg2
,
LLVMDivideInstruction
.
DivisionType
.
UNSIGNEDINT
,
"div"
);
}
public
LLVMValue
LLVMCallFunctionInstruction
(
ASTLispNode
node
)
throws
Exception
{
LLVMFunction
func
=
functions
.
get
(
node
.
caption
);
int
size
=
node
.
parameters
.
size
();
LLVMValue
[]
args
=
new
LLVMValue
[
size
];
for
(
int
i
=
0
;
i
<
size
;
i
++){
args
[
i
]
=
eval
(
node
.
parameters
.
get
(
i
));
}
// long argsNum = Core.LLVMCountParamTypes(Core.LLVMTypeOf(func.getInstance()));
SWIGTYPE_p_p_LLVMOpaqueValue
args_opaque
=
Core
.
new_LLVMValueRefArray
(
args
.
length
);
for
(
int
i
=
0
;
i
<
args
.
length
;
i
++)
Core
.
LLVMValueRefArray_setitem
(
args_opaque
,
i
,
args
[
i
].
getInstance
());
SWIGTYPE_p_LLVMOpaqueValue
instance
=
Core
.
LLVMBuildCall
(
builder
.
getInstance
(),
func
.
getInstance
(),
args_opaque
,
args
.
length
,
node
.
caption
+
"aaa"
);
Core
.
delete_LLVMValueRefArray
(
args_opaque
);
return
new
LLVMValue
(
instance
);
//return new LLVMCallInstruction(builder, func, args, node.caption);
}
public
LLVMValue
eval
(
ASTLispNode
node
)
throws
Exception
{
if
(
node
instanceof
ASTLispConstantNode
){
return
LLVMConstantInteger
.
constantInteger
(
LLVMIntegerType
.
i32
,
((
ASTLispConstantNode
)
node
).
value
,
false
);
}
String
instruction
=
opcodes
.
get
(
node
.
caption
);
if
(
instruction
!=
null
)
{
Method
invoker
=
this
.
getClass
().
getDeclaredMethod
(
instruction
,
ASTLispNode
.
class
);
return
(
LLVMValue
)
invoker
.
invoke
(
this
,
node
);
}
LLVMValue
arg
=
arguments
.
get
(
node
.
caption
);
if
(
arg
!=
null
){
return
arg
;
}
if
(
functions
.
containsKey
(
node
.
caption
)){
return
LLVMCallFunctionInstruction
(
node
);
}
throw
new
Exception
(
"Cant evaluate symbol: "
+
node
.
caption
);
}
}
}
class
LispJITRunnerWrapper
extends
LLVMExecutionEngine
{
LispJITRunnerWrapper
(
LLVMModule
module
)
throws
Exception
{
super
();
SWIGTYPE_p_p_LLVMOpaqueExecutionEngine
engines
=
ExecutionEngine
.
new_LLVMExecutionEngineRefArray
(
1
);
SWIGTYPE_p_p_char
outerrs
=
ExecutionEngine
.
new_StringArray
(
1
);
int
success
=
ExecutionEngine
.
LLVMCreateJITCompilerForModule
(
engines
,
module
.
getInstance
(),
0
,
outerrs
);
String
outerr
=
ExecutionEngine
.
StringArray_getitem
(
outerrs
,
0
);
ExecutionEngine
.
delete_StringArray
(
outerrs
);
outerrs
=
null
;
instance
=
ExecutionEngine
.
LLVMExecutionEngineRefArray_getitem
(
engines
,
0
);
ExecutionEngine
.
delete_LLVMExecutionEngineRefArray
(
engines
);
engines
=
null
;
/*
if(success == 0)
throw new Exception(outerr);
*
*/
}
}
Event Timeline
Log In to Comment