Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Sven Gestegård Robertz
LabComm
Commits
2d0cba67
Commit
2d0cba67
authored
Jul 23, 2013
by
Sven Robertz
Browse files
cleanup etc
parent
ac1eb49e
Changes
4
Hide whitespace changes
Inline
Side-by-side
examples/dynamic/README
View file @
2d0cba67
This directory contains a small example of how to generate and compile
a labcomm endpoint on the fly.
This directory contains a small example of how to generate and compile a
labcomm endpoint on the fly.
the script static.sh builds and runs a very simple static labcomm demo
the script dynamic.sh builds and runs an example where labcomm is generated and woven
togerther with user-defined handler code.
the script dynamic.sh builds and runs an example where labcomm is generated and
woven togerther with user-defined handler code.
the test.sh script builds and runs the TestLabCommGen, which illustrates the
on-the-fly compilation to RAM, reading the labcomm declarations and handlers from file
The handlers declaration (in handlers.txt) is experimental, and has the following format:
the test.sh script builds and runs the TestLabCommGen, which illustrates the
on-the-fly compilation to RAM, reading the labcomm declarations and handlers
from file
<sample name>:handler(<data type> <variable name>) {
<handler method code>
}###
where the end marker (}###) is a kludge to avoid having to parse the method body while still allowing
it to contain blocks. Thus, having the sequence "}###" in the method body breaks this. Caveat hacker!
The handlers declaration (in handlers.txt, handlers2.txt) is experimental, and has the
following format:
<sample name>:handler(<data type> <variable name>) { <handler method code> }###
where the end marker (}###) is a kludge to avoid having to parse the method
body while still allowing it to contain blocks. Thus, having the sequence
"}###" in the method body breaks this. Caveat hacker!
An example handlers declaration:
foo:handler(foo value) {
System.out.println("foo handler from handlers.txt");
test.HandlerContext ctx = (test.HandlerContext)context;
System.out.println("foo handler from handlers2.txt");
System.out.println("using context "+ctx.str);
ctx.x = value.x + 1000;
ctx.y = value.y + 1000;
ctx.z = value.z + 1000;
System.out.println(value.x);
System.out.println(value.y);
System.out.println(value.z);
...
...
@@ -32,7 +41,18 @@ foo:handler(foo value) {
System.out.println();
}###
bar:handler(int value) {
System.out.println(value);
System.out.println("bar:"+value);
test.HandlerContext ctx = (test.HandlerContext)context;
ctx.bar = value + 1000;
}###
Note that parameters differ: the value for foo is an object but for bar it is a primitive type (int) value.
Note that parameters differ: the value for foo is an object but for bar it is a
primitive type (int) value.
The context in the example is a kludge or placeholder for tying the
user-provided handler methods to the environment they are executed in, and
allowing state to be kept between invokations. The class containing the handler
methods have an attribute, Object context, and its initialization is currently
hard coded. The permanent solution is TBD.
examples/dynamic/test/DynamicPart.java
View file @
2d0cba67
...
...
@@ -75,13 +75,13 @@ public class DynamicPart {
generateHandlers
(
srcStr
,
handlers
);
System
.
out
.
println
(
"*** Generated handler source:"
);
//
System.out.println("*** Generated handler source:");
handlers
.
keySet
();
for
(
String
n
:
handlers
.
keySet
())
{
System
.
out
.
println
(
n
+
":"
);
System
.
out
.
println
(
handlers
.
get
(
n
));
}
//
for (String n : handlers.keySet()) {
//
System.out.println(n+":");
//
System.out.println(handlers.get(n));
//
}
InRAMCompiler
irc
=
generateCode
(
labcommStr
,
handlers
);
...
...
@@ -95,12 +95,10 @@ public class DynamicPart {
public
static
void
generateHandlers
(
String
srcStr
,
HashMap
<
String
,
String
>
handlers
)
{
int
pos
=
0
;
while
(
pos
<
srcStr
.
length
())
{
// System.out.println("--------");
int
nameEnd
=
srcStr
.
indexOf
(
':'
,
pos
);
if
(
nameEnd
<
0
)
break
;
String
name
=
srcStr
.
substring
(
pos
,
nameEnd
);
// System.out.println("Name="+name);
pos
=
nameEnd
+
1
;
String
par
=
""
;
...
...
@@ -108,7 +106,6 @@ public class DynamicPart {
if
(
srcStr
.
startsWith
(
handler_decl
,
pos
))
{
int
endPar
=
srcStr
.
indexOf
(
')'
,
pos
);
par
=
srcStr
.
substring
(
pos
+
handler_decl
.
length
(),
endPar
);
// System.out.println("param="+par);
pos
=
endPar
+
1
;
}
else
{
System
.
out
.
println
(
"expeced handler decl:\n"
+
srcStr
.
substring
(
pos
));
...
...
@@ -116,14 +113,9 @@ public class DynamicPart {
int
bodyEnd
=
srcStr
.
indexOf
(
"}###"
,
pos
);
// HERE BE DRAGONS! a bit brittle
String
body
=
srcStr
.
substring
(
pos
,
bodyEnd
+
1
);
pos
=
bodyEnd
+
5
;
// System.out.println("body:");
// System.out.println(body);
// System.out.println("**** generates:");
HandlerSrc
s
=
new
HandlerSrc
(
name
,
par
,
body
);
final
String
genSrc
=
s
.
getSrc
();
// System.out.println(genSrc);
handlers
.
put
(
name
,
genSrc
);
}
}
...
...
@@ -211,7 +203,7 @@ public class DynamicPart {
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
System
.
out
.
println
(
"Generated labcomm code:"
);
//
System.out.println("Generated labcomm code:");
InRAMCompiler
irc
=
new
InRAMCompilerJavax
(
"labcomm.generated"
,
TestLabcommGen
.
class
.
getClassLoader
());
...
...
@@ -219,12 +211,12 @@ public class DynamicPart {
StringBuilder
handlerMethods
=
new
StringBuilder
();
handlerClass
.
append
(
"package labcomm.generated;\n"
);
handlerClass
.
append
(
"import test.TestLabcommGen;\n"
);
handlerClass
.
append
(
"public class "
+
handlerClassName
+
" implements "
);
String
handlerAttributes
=
"Object context;\n"
;
String
handlerConstructor
=
"public "
+
handlerClassName
+
"(Object context){ this.context=context;}\n"
;
String
handlerConstr
=
"public "
+
handlerClassName
+
"(){super();}\n"
;
String
handlerConstrCtxt
=
"public "
+
handlerClassName
+
"(Object context){ this.context=context;}\n"
;
Iterator
<
String
>
i
=
genCode
.
keySet
().
iterator
();
try
{
...
...
@@ -237,12 +229,13 @@ public class DynamicPart {
}
handlerMethods
.
append
(
handlers
.
get
(
sampleName
));
handlerMethods
.
append
(
"\n"
);
System
.
out
.
println
(
"***"
+
sampleName
+
"\n"
+
src
);
//
System.out.println("***"+sampleName+"\n"+src);
irc
.
compile
(
sampleName
,
src
);
// while iterating, compile the labcomm generated code
}
handlerClass
.
append
(
"{\n"
);
handlerClass
.
append
(
handlerAttributes
);
handlerClass
.
append
(
handlerConstructor
);
handlerClass
.
append
(
handlerConstr
);
handlerClass
.
append
(
handlerConstrCtxt
);
handlerClass
.
append
(
handlerMethods
.
toString
());
handlerClass
.
append
(
"}\n"
);
...
...
@@ -270,55 +263,6 @@ public class DynamicPart {
return
irc
;
}
/** generate labcomm code and compile handlers. Version for separate handler classes
*
* @param lcAST - the AST of the labcomm declaration
* @param handlers - a map <name, source> of handlers for the types in ast
* @return an InRAMCompiler object containing the generated clases
*/
private
static
InRAMCompiler
handleAstSeparate
(
Program
lcAST
,
HashMap
<
String
,
String
>
handlers
)
{
Map
<
String
,
String
>
genCode
=
new
HashMap
<
String
,
String
>();
try
{
lcAST
.
J_gen
(
genCode
,
"labcomm.generated"
);
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
System
.
out
.
println
(
"Generated labcomm code:"
);
InRAMCompiler
irc
=
new
InRAMCompilerJavax
(
"labcomm.generated"
,
null
);
Iterator
<
String
>
i
=
genCode
.
keySet
().
iterator
();
while
(
i
.
hasNext
()){
final
String
sampleName
=
i
.
next
();
final
String
src
=
genCode
.
get
(
sampleName
);
System
.
out
.
println
(
"***"
+
sampleName
+
"\n"
+
src
);
StringBuilder
sb
=
new
StringBuilder
();
sb
.
append
(
"package labcomm.generated;\n"
);
sb
.
append
(
"public class gen_"
+
sampleName
+
"Handler implements "
+
sampleName
+
".Handler {\n"
);
sb
.
append
(
handlers
.
get
(
sampleName
));
sb
.
append
(
"}\n"
);
System
.
out
.
println
(
"-------------------------------------"
);
System
.
out
.
println
(
sb
.
toString
());
try
{
irc
.
compile
(
sampleName
,
src
);
irc
.
compile
(
"gen_"
+
sampleName
+
"Handler"
,
sb
.
toString
());
}
catch
(
IllegalArgumentException
e
)
{
e
.
printStackTrace
();
}
catch
(
SecurityException
e
)
{
e
.
printStackTrace
();
}
catch
(
ClassNotFoundException
e
)
{
e
.
printStackTrace
();
}
catch
(
IllegalAccessException
e
)
{
e
.
printStackTrace
();
}
catch
(
InvocationTargetException
e
)
{
e
.
printStackTrace
();
}
catch
(
NoSuchMethodException
e
)
{
e
.
printStackTrace
();
}
System
.
out
.
println
(
"================================"
);
}
return
irc
;
}
/** test method
*/
private
void
decodeTest
(
InRAMCompiler
irc
,
HandlerContext
ctxt
,
String
tmpFile
,
String
...
sampleNames
)
{
...
...
@@ -450,82 +394,4 @@ public class DynamicPart {
e
.
printStackTrace
();
}
}
/** test method
*/
private
static
void
decodeTestSeparate
(
InRAMCompiler
irc
,
String
tmpFile
,
String
...
sampleNames
)
{
try
{
FileInputStream
in
=
new
FileInputStream
(
tmpFile
);
LabCommDecoderChannel
dec
=
new
LabCommDecoderChannel
(
in
);
for
(
String
sampleName
:
sampleNames
)
{
System
.
out
.
println
(
"registering handler for "
+
sampleName
);
Class
sampleClass
=
irc
.
load
(
sampleName
);
Class
handlerClass
=
irc
.
load
(
"gen_"
+
sampleName
+
"Handler"
);
Class
handlerInterface
=
irc
.
load
(
sampleName
+
"$Handler"
);
Object
handler
=
handlerClass
.
newInstance
();
Method
reg
=
sampleClass
.
getDeclaredMethod
(
"register"
,
LabCommDecoder
.
class
,
handlerInterface
);
reg
.
invoke
(
sampleClass
,
dec
,
handler
);
}
try
{
System
.
out
.
println
(
"*** decoding:"
);
dec
.
run
();
}
catch
(
EOFException
e
)
{
System
.
out
.
println
(
"*** reached EOF ***"
);
}
in
.
close
();
}
catch
(
Throwable
e
)
{
e
.
printStackTrace
();
}
}
/** dummy test creating instances of sample and handler, and calling handle*/
private
static
void
dummyTestSeparate
(
InRAMCompiler
irc
)
{
try
{
Class
hc
=
irc
.
load
(
"gen_"
+
SAMPLE_NAME_FOO
+
"Handler"
);
Object
h
=
hc
.
newInstance
();
Class
fc
=
irc
.
load
(
SAMPLE_NAME_FOO
);
Object
f
=
fc
.
newInstance
();
Field
x
=
fc
.
getDeclaredField
(
"x"
);
Field
y
=
fc
.
getDeclaredField
(
"y"
);
Field
z
=
fc
.
getDeclaredField
(
"z"
);
x
.
setInt
(
f
,
10
);
y
.
setInt
(
f
,
11
);
z
.
setInt
(
f
,
12
);
Method
m
;
try
{
m
=
hc
.
getDeclaredMethod
(
"handle_"
+
SAMPLE_NAME_FOO
,
fc
);
m
.
invoke
(
h
,
f
);
}
catch
(
SecurityException
e
)
{
// TODO Auto-generated catch block
e
.
printStackTrace
();
}
catch
(
NoSuchMethodException
e
)
{
// TODO Auto-generated catch block
e
.
printStackTrace
();
}
catch
(
IllegalArgumentException
e
)
{
// TODO Auto-generated catch block
e
.
printStackTrace
();
}
catch
(
InvocationTargetException
e
)
{
// TODO Auto-generated catch block
e
.
printStackTrace
();
}
}
catch
(
ClassNotFoundException
e
)
{
e
.
printStackTrace
();
}
catch
(
InstantiationException
e
)
{
// TODO Auto-generated catch block
e
.
printStackTrace
();
}
catch
(
IllegalAccessException
e
)
{
// TODO Auto-generated catch block
e
.
printStackTrace
();
}
catch
(
SecurityException
e
)
{
// TODO Auto-generated catch block
e
.
printStackTrace
();
}
catch
(
NoSuchFieldException
e
)
{
// TODO Auto-generated catch block
e
.
printStackTrace
();
}
}
}
examples/dynamic/test/InRAMCompilerJavax.java
View file @
2d0cba67
...
...
@@ -48,6 +48,8 @@ import javax.tools.ToolProvider;
public
class
InRAMCompilerJavax
implements
InRAMCompiler
{
private
boolean
debug
;
// Source for both test classes. They go in package
// "just.generated"
...
...
@@ -127,6 +129,18 @@ public class InRAMCompilerJavax implements InRAMCompiler {
createNewClassLoader
(
providedClassLoader
);
}
/**
*
* @param pkgName - The package for the generated classes. The source code must only contain classes in this package.
* @param cl - An optional (i.e., may be null) classloader that is also searched
*
* @param debug - set to true to turn on debug output
*/
public
InRAMCompilerJavax
(
String
pkgName
,
ClassLoader
cl
,
boolean
debug
)
{
this
(
pkgName
,
cl
);
this
.
debug
=
debug
;
}
/* (non-Javadoc)
* @see se.lth.cs.sven.rosettaTest.cc.InRAMCompiler#deleteClass(java.lang.String)
...
...
@@ -202,7 +216,9 @@ public class InRAMCompilerJavax implements InRAMCompiler {
jfm
.
isCompiling
(
false
);
// Traces the classes now found in the cache
System
.
out
.
println
(
"\nInRAMCompiler: generated classes = "
+
output
.
keySet
());
if
(
debug
)
{
System
.
out
.
println
(
"\nInRAMCompiler: generated classes = "
+
output
.
keySet
());
}
}
/* (non-Javadoc)
...
...
@@ -378,7 +394,9 @@ trick:
RAMClassLoader
(
Map
<
String
,
JavaFileObject
>
output
,
ClassLoader
cl
)
{
this
.
output
=
output
;
this
.
classLoader
=
cl
;
testGetResources
();
if
(
debug
)
{
testGetResources
();
}
}
private
void
testGetResources
()
{
...
...
@@ -395,8 +413,10 @@ trick:
try
{
//XXX This is a hack! Look in "parent" class loader first, to find correct Service instances.
if
(
classLoader
!=
null
)
{
System
.
out
.
println
(
"RAMClassLoader.findClass: getResource (package): "
+
classLoader
.
getResource
(
"se/lth/cs/sven/rosettaTest"
));
System
.
out
.
println
(
"RAMClassLoader.findClass: getResource: "
+
classLoader
.
getResource
(
"se/lth/cs/sven/rosettaTest/Constraint.class"
));
if
(
debug
)
{
System
.
out
.
println
(
"RAMClassLoader.findClass: getResource (package): "
+
classLoader
.
getResource
(
"se/lth/cs/sven/rosettaTest"
));
System
.
out
.
println
(
"RAMClassLoader.findClass: getResource: "
+
classLoader
.
getResource
(
"se/lth/cs/sven/rosettaTest/Constraint.class"
));
}
try
{
Class
<?>
c
=
classLoader
.
loadClass
(
name
);
...
...
examples/dynamic/test/TestLabcommGen.java
View file @
2d0cba67
...
...
@@ -208,7 +208,7 @@ public class TestLabcommGen {
}
System
.
out
.
println
(
"Generated labcomm code:"
);
InRAMCompiler
irc
=
new
InRAMCompilerJavax
(
"labcomm.generated"
,
TestLabcommGen
.
class
.
getClassLoader
());
InRAMCompiler
irc
=
new
InRAMCompilerJavax
(
"labcomm.generated"
,
TestLabcommGen
.
class
.
getClassLoader
()
,
true
);
StringBuilder
handlerClass
=
new
StringBuilder
();
StringBuilder
handlerMethods
=
new
StringBuilder
();
...
...
@@ -219,7 +219,8 @@ public class TestLabcommGen {
String
handlerAttributes
=
"Object context;\n"
;
String
handlerConstructor
=
"public "
+
handlerClassName
+
"(Object context){ this.context=context;}\n"
;
String
handlerConstr
=
"public "
+
handlerClassName
+
"(){ super();}\n"
;
String
handlerConstrCtxt
=
"public "
+
handlerClassName
+
"(Object context){ this.context=context;}\n"
;
Iterator
<
String
>
i
=
genCode
.
keySet
().
iterator
();
try
{
...
...
@@ -237,7 +238,8 @@ public class TestLabcommGen {
}
handlerClass
.
append
(
"{\n"
);
handlerClass
.
append
(
handlerAttributes
);
handlerClass
.
append
(
handlerConstructor
);
handlerClass
.
append
(
handlerConstr
);
handlerClass
.
append
(
handlerConstrCtxt
);
handlerClass
.
append
(
handlerMethods
.
toString
());
handlerClass
.
append
(
"}\n"
);
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment