Skip to content
Browse files

[java:bugfix] make a Lexpad object to resemble the struct Lexpad in d…

…otnet
  • Loading branch information...
1 parent 1c5881f commit c025d33d2163c477710e29900c59835197d9a058 @mberends mberends committed
View
4 .gitignore
@@ -7,5 +7,7 @@
gen_*
dotnet/compiler/x.*
dotnet/compiler/NQPSetting.cs
-java/compiler/x.*
dotnet/runtime/obj/*
+java/compiler/x.*
+java/compiler/NQPSetting.*
+java/compiler/RakudoOutput.*
View
41 java/compiler/JST2Java.pm
@@ -1,8 +1,9 @@
-# This compiles a Java Syntax Tree down to Java.
+# Compile a Java Syntax Tree down to Java.
class JST2JavaCompiler;
method compile(JST::Node $node) {
my $*CUR_ID := 0;
+ my %*CUR_ID;
return java_for($node);
}
@@ -12,6 +13,16 @@ sub get_unique_id($prefix) {
return $prefix ~ '_' ~ $*CUR_ID;
}
+# A slightly troubleshooting-friendlier alternative to get_unique_id
+sub get_unique_global_name($prefix, $suffix) {
+ my $number := 1;
+ if %*CUR_ID{$prefix} > 0 { $number := %*CUR_ID{$prefix} + 1; }
+ %*CUR_ID{$prefix} := $number;
+ my $result := $prefix ~ '_' ~ $number;
+ if $suffix ne '' { $result := $result ~ '_' ~ $suffix; }
+ return $result;
+}
+
our multi sub java_for(JST::CompilationUnit $node) {
my @*USINGS;
my $main := '';
@@ -79,7 +90,7 @@ our multi sub java_for(JST::Stmts $stmts) {
our multi sub java_for(JST::TryFinally $tf) {
unless +@($tf) == 2 { pir::die('JST::TryFinally nodes must have 2 children') }
- my $try_result := get_unique_id('try_result');
+ my $try_result := get_unique_global_name('try_result','');
my $code := " RakudoObject $try_result; // JST::TryFinally\n" ~
" try \{\n" ~
java_for((@($tf))[0]);
@@ -106,10 +117,9 @@ our multi sub java_for(JST::MethodCall $mc) {
# Code-gen the call.
$code := $code ~ ' ';
- my $ret_type := $mc.type || 'var'; # TODO: delete
unless $mc.void {
- $*LAST_TEMP := get_unique_id('result');
- # TODO my $ret_type := $mc.type || 'var';
+ my $ret_type := $mc.type || 'var';
+ $*LAST_TEMP := get_unique_global_name('result','methcall');
my $method_name := "$invocant." ~ $mc.name;
if $ret_type eq 'var' && $method_name eq 'Ops.unbox_str'
{
@@ -139,16 +149,14 @@ our multi sub java_for(JST::MethodCall $mc) {
$method_name eq 'Ops.mul_int' ||
$method_name eq 'Ops.sub_int' ||
$method_name eq 'StaticBlockInfo[1].StaticLexPad.SetByName' # WTF?
- )
- {
+ ) {
$ret_type := 'RakudoObject';
}
$code := $code ~ "$ret_type $*LAST_TEMP = ";
+ if $ret_type eq 'var' { $code := $code ~ "// var should be " ~ $invocant ~ "." ~ $mc.name ~ "\n"; }
}
$code := $code ~ "$invocant." ~ $mc.name ~
"(" ~ pir::join(', ', @arg_names) ~ "); // JST::MethodCall\n";
- if $ret_type eq 'var' { $code := $code ~ "// var should be " ~ $invocant ~ "." ~ $mc.name ~ "\n"; }
-
return $code;
}
@@ -164,7 +172,7 @@ our multi sub java_for(JST::Call $mc) {
# Code-gen the call.
$code := $code ~ ' ';
unless $mc.void {
- $*LAST_TEMP := get_unique_id('result');
+ $*LAST_TEMP := get_unique_global_name('result','call');
$code := $code ~ "RakudoObject $*LAST_TEMP = ";
}
$code := $code ~ $mc.name ~
@@ -183,13 +191,14 @@ our multi sub java_for(JST::New $new) {
}
# Code-gen the constructor call.
- $*LAST_TEMP := get_unique_id('new');
+ $*LAST_TEMP := get_unique_global_name('new','');
$code := $code ~ " " ~ $new.type ~ " $*LAST_TEMP = new ";
+ $code := $code ~ $new.type;
if $new.type eq 'RakudoCodeRef.IFunc_Body' {
- $code := $code ~ $new.type ~ "() \{ public RakudoObject Invoke( ThreadContext TC, RakudoObject Obj, RakudoObject Cap ) \{ return ((RakudoCodeRef.Instance)Obj).Body.Invoke(TC, Obj, Cap);\}\}";
+ $code := $code ~ "() \{ public RakudoObject Invoke( ThreadContext TC, RakudoObject Obj, RakudoObject Cap ) \{ return ((RakudoCodeRef.Instance)Obj).Body.Invoke(TC, Obj, Cap);\}\}";
}
else {
- $code := $code ~ $new.type ~ "(" ~ pir::join(', ', @arg_names) ~ ")";
+ $code := $code ~ "(" ~ pir::join(', ', @arg_names) ~ ")";
}
$code := $code ~ "; // JST::New\n";
return $code;
@@ -199,7 +208,7 @@ our multi sub java_for(JST::If $if) {
unless +@($if) >= 2 { pir::die('A JST::If node must have at least 2 children') }
# Need a variable to put the final result in.
- my $if_result := get_unique_id('if_result');
+ my $if_result := get_unique_global_name('if_result','');
# Get the conditional and emit if.
my $code := java_for((@($if))[0]);
@@ -283,7 +292,7 @@ our multi sub java_for(JST::ArrayLiteral $al) {
}
# Code-gen the array.
- $*LAST_TEMP := get_unique_id('arr');
+ $*LAST_TEMP := get_unique_global_name('arr','arrayliteral');
return $code ~ " " ~ $al.type ~ "[] $*LAST_TEMP = new " ~ $al.type ~ '[] {' ~
pir::join(',', @item_names) ~ "}; // JST::ArrayLiteral\n";
}
@@ -302,7 +311,7 @@ our multi sub java_for(JST::DictionaryLiteral $dl) {
}
# Code-gen the dictionary.
- $*LAST_TEMP := get_unique_id('dic');
+ $*LAST_TEMP := get_unique_global_name('dic','dictionaryliteral');
return $code ~ " HashMap<" ~ $dl.key_type ~ ', ' ~ $dl.value_type ~ "> $*LAST_TEMP = new HashMap<" ~
$dl.key_type ~ ', ' ~ $dl.value_type ~ ">(); // JST::DictionaryLiteral\n" ~
" $*LAST_TEMP.put" ~
View
8 java/compiler/Makefile
@@ -24,14 +24,16 @@ gen_jst.pir: JST.pm
gen_jst2java.pir: JST2Java.pm
parrot-nqp --target=pir JST2Java.pm > gen_jst2java.pir
-NQPSetting.jar: ../../common/NQP/NQPSetting.pm \
+NQPSetting.java: ../../common/NQP/NQPSetting.pm \
gen_actions.pir \
gen_grammar.pir \
gen_jst.pir \
gen_past2jst.pir \
gen_jst2java.pir
- parrot compile.pir ../../common/NQP/NQPSetting.pm --setting > gen_nqpsetting.java
- $(JAVAC) -classpath ../runtime/RakudoRuntime.jar gen_nqpsetting.java
+ parrot compile.pir ../../common/NQP/NQPSetting.pm --setting > NQPSetting.java
+
+NQPSetting.jar: NQPSetting.java
+ $(JAVAC) -classpath ../runtime/RakudoRuntime.jar NQPSetting.java
jar cf NQPSetting.jar -C $(CLASSES) .
test: all
View
3 java/compiler/PAST2JSTCompiler.pm
@@ -109,9 +109,12 @@ method compile(PAST::Node $node) {
));
}
else {
+ my @params;
+ @params.push('String[] args');
$class.push(JST::Method.new(
:name('main'), # Main in the C# version
:return_type('void'),
+ :params(@params),
JST::Temp.new( :name('TC'), :type('ThreadContext'),
JST::MethodCall.new(
:on('Rakudo.Init'), :name('Initialize'), :type('ThreadContext'),
View
5 java/compiler/try.sh
@@ -4,8 +4,9 @@ if expr "$1" = "" > /dev/null; then
echo Usage: ./try.sh '<Perl 6 source file>'
exit 1
fi
-make || exit 2
+( echo -n 'runtime: '; cd ../runtime; make; ) # re-build runtime/RakudoRuntime.jar if necessary
+echo -n 'compiler: '; make || exit 2
parrot compile.pir $1 > RakudoOutput.java || exit 3
javac -classpath ../runtime/RakudoRuntime.jar RakudoOutput.java || exit 4
echo ---
-java -classpath ../runtime/RakudoRuntime.jar RakudoOutput.class
+java -classpath classes:../runtime/RakudoRuntime.jar:. RakudoOutput
View
54 java/runtime/Rakudo/Init.java
@@ -43,8 +43,9 @@ public static ThreadContext Initialize(String settingName)
// Either load a named setting or use the fake bootstrapping one.
Context settingContext =
- (settingName != null) ? LoadSetting(settingName, knowHOW)
- : BootstrapSetting(knowHOW);
+ // Comment out the next line to always use the fake Setting.
+ (settingName != null) ? LoadSetting(settingName, knowHOW) :
+ BootstrapSetting(knowHOW);
// Cache native capture and LLCode type object.
CaptureHelper.CaptureTypeObject = settingContext.LexPad.GetByName("capture");
@@ -61,7 +62,7 @@ public static ThreadContext Initialize(String settingName)
threadContext.DefaultStrBoxType = settingContext.LexPad.GetByName("NQPStr");
return threadContext;
}
-
+
/// <summary>
/// Registers all of the built-in representations.
/// </summary>
@@ -90,6 +91,7 @@ private static void RegisterRepresentations()
/// <returns></returns>
private static Context BootstrapSetting(RakudoObject KnowHOW)
{
+ System.err.println( "calling new Context from Init" );
Context settingContext = new Context();
settingContext.LexPad = new Lexpad(new String[]
{ "KnowHOW", "capture", "NQPInt", "NQPNum", "NQPStr", "LLCode", "list" });
@@ -123,41 +125,61 @@ public RakudoObject Invoke(ThreadContext tc, RakudoObject self, RakudoObject cap
/// <param name="Name"></param>
/// <param name="KnowHOW"></param>
/// <returns></returns>
- public static Context LoadSetting(String name, RakudoObject knowHOW)
+ public static Context LoadSetting(String settingName, RakudoObject knowHOW)
{
// Load the assembly.
- // var settingAssembly = AppDomain.CurrentDomain.Load(Name);
+ System.err.println("Init.LoadSetting begin loading " + settingName );
ClassLoader loader = ClassLoader.getSystemClassLoader();
- Class<?> classNQPSetting; // grrr, a wildcard type :-(
+ Class<?> classNQPSetting = null; // grrr, a wildcard type :-(
try {
- classNQPSetting = loader.loadClass(name);
+ classNQPSetting = loader.loadClass(settingName);
}
catch (ClassNotFoundException ex) {
- classNQPSetting = null;
- System.err.println("Class " + name + " not found: " + ex.getMessage());
+ System.err.println("Class " + settingName + " not found: " + ex.getMessage());
+ System.exit(1);
+ }
+ catch ( Exception ex ) {
+ System.err.println("loadClass(\"" + settingName + "\") exception: " + ex.getMessage());
+ System.exit(1);
+ }
+
+ // TODO: remove
+ if ( classNQPSetting == null ) {
+ System.err.println("classNQPSetting is null");
System.exit(1);
}
// Find the setting type and its LoadSetting method.
// var Class = settingAssembly.GetType("NQPSetting");
// var Method = Class.GetMethod("LoadSetting", BindingFlags.NonPublic | BindingFlags.Static);
- String s = new String();
- Class stringClass = s.getClass();
- java.lang.reflect.Method methodLoadSetting;
+// String s = new String();
+// Class stringClass = s.getClass();
+ java.lang.reflect.Method methodLoadSetting = null;
try {
- methodLoadSetting = classNQPSetting.getMethod("LoadSetting", stringClass);
+ methodLoadSetting = classNQPSetting.getMethod("LoadSetting");
}
catch ( NoSuchMethodException ex) {
- methodLoadSetting = null;
System.err.println("Method LoadSetting not found: " + ex.getMessage());
System.exit(1);
}
+ catch ( Exception ex ) {
+ System.err.println("getMethod(\"LoadSetting\") exception: " + ex.getMessage());
+ System.exit(1);
+ }
+
+ // TODO: remove
+ if ( methodLoadSetting == null ) {
+ System.err.println("methodLoadSetting is null");
+ System.exit(1);
+ }
+ else {
+ System.err.println("methodLoadSetting is ok: " + methodLoadSetting );
+ }
// Run it to get the context we want.
- // Context settingContext = (Context)Method.Invoke(null, new Object[] { });
Context settingContext = null;
try {
- settingContext = (Context)methodLoadSetting.invoke( null, s );
+ settingContext = (Context)methodLoadSetting.invoke( null );
}
catch (IllegalAccessException ex) {
System.err.println("Illegal access: " + ex.getMessage());
View
18 java/runtime/Rakudo/Runtime/Context.java
@@ -38,8 +38,10 @@
/// <summary>
/// Creates an empty, uninitialized context.
/// </summary>
- public Context()
+ public Context() // it could be private, except that Init() calls it.
{
+ System.err.println( "new empty Context created" );
+ this.LexPad = new Lexpad( new String[] {} ); // parameter is an empty list of strings
}
/// <summary>
@@ -57,10 +59,18 @@ public Context(RakudoCodeRef.Instance staticCodeObject, Context caller, RakudoOb
// Static sub object should have this as the current
// context.
staticCodeObject.CurrentContext = this;
+
+ this.LexPad = new Lexpad( new String[] {} ); // parameter is an empty list of strings
+ // TODO: remove
+ if ( this.LexPad == null ) {
+ System.err.println( "this.LexPad is null in Context.java" );
+ System.exit(1);
+ }
- // Lex pad should be copy of the static one.
- // XXX This isn't quite what we want in the long run, but it
- // does fine for now.
+ // Lex pad should be an "instantiation" of the static one.
+ // Instantiating a lexpad creates a new dynamic instance of it
+ // from a static one, copying over the slot storage entries
+ // from the static one but sharing the slot mapping.
this.LexPad.SlotMapping = StaticCodeObject.StaticLexPad.SlotMapping;
this.LexPad.Storage = (RakudoObject[])StaticCodeObject.StaticLexPad.Storage.clone();
View
9 java/runtime/Rakudo/Runtime/Lexpad.java
@@ -7,7 +7,7 @@
/// Represents a lexpad - either the static version or the dynamic
/// one.
/// </summary>
-public class Lexpad
+public class Lexpad // struct in the C# version
{
/// <summary>
/// This is the slot mapping, allocating names to slots. All the
@@ -30,8 +30,11 @@ public Lexpad(String[] SlotNames)
{
SlotMapping = new HashMap<String, Integer>(SlotNames.length);
int Slot = 0;
- for (String Name : SlotNames)
+ for (String Name : SlotNames) {
SlotMapping.put(Name, Slot++);
+ // System.err.println("adding into LexPad: " + Name);
+ }
+ // System.err.println("LexPad SlotNames length: " + SlotNames.length);
Storage = new RakudoObject[SlotNames.length];
}
@@ -57,7 +60,7 @@ public RakudoObject SetByName(String Name, RakudoObject Value)
}
/// <summary>
- /// Extends the lexpad with an extra slot.
+ /// Extends the lexpad with an extra slot. TODO: optimize if possible
/// </summary>
/// <param name="Name"></param>
public void Extend(String[] Names)

0 comments on commit c025d33

Please sign in to comment.
Something went wrong with that request. Please try again.