changeset 7292:213c1297a814

Simple Language: A simple dynamic programming language to demonstrate Truffle features
author Christian Wimmer <christian.wimmer@oracle.com>
date Fri, 21 Dec 2012 10:45:37 -0800
parents a748e4d44694
children 4974776828ec
files graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/AbstractTest.java graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/AddTest.java graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/ComparisonTest.java graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/LoopPrintTest.java graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/LoopTest.java graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/MulTest.java graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SplitOutputStream.java graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SumTest.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/NodeFactory.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLArguments.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SimpleLanguage.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/BlockNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/BreakException.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/BreakNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ConditionNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ContinueException.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ContinueNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ControlFlowException.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/FunctionDefinitionNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/IfNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/PrintNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ReturnException.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ReturnNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/StatementNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/WhileNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/ops/AddOp.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/ops/BigIntegerLiteral.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/ops/IfOp.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/ops/IntegerLiteral.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/ops/LessThanOp.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/ops/LogicalAndOp.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/ops/MulOp.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/ops/ReadLocalOp.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/ops/StringLiteral.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/ops/TimeOp.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/ops/WriteLocalOp.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Copyright.frame graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Parser.frame graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Parser.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Scanner.frame graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Scanner.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/SimpleLanguage.atg graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/tools/GraphPrinter.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/types/FrameSlotNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/types/TypedNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/types/Types.java mx/projects
diffstat 47 files changed, 4046 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/AbstractTest.java	Fri Dec 21 10:45:37 2012 -0800
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.sl.test;
+
+import java.io.*;
+
+import org.junit.*;
+
+import com.oracle.truffle.sl.*;
+
+public class AbstractTest {
+    public static final int REPEATS = 10;
+    private static final String NEWLINE = System.getProperty("line.separator");
+
+    private static String concat(String[] string) {
+        StringBuilder result = new StringBuilder();
+        for (String s : string) {
+            result.append(s).append(NEWLINE);
+        }
+        return result.toString();
+    }
+
+    private static String repeat(String s, int count) {
+        StringBuilder result = new StringBuilder(s.length() * count);
+        for (int i = 0; i < count; i++) {
+            result.append(s);
+        }
+        return result.toString();
+    }
+
+    protected void executeSL(String[] input, String[] expectedOutput, boolean useConsole) {
+        InputStream in = new ByteArrayInputStream(concat(input).getBytes());
+
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        PrintStream printer = new PrintStream(useConsole ? new SplitOutputStream(out, System.err) : out);
+        PrintStream origErr = System.err;
+        System.setErr(printer);
+
+        SimpleLanguage.run(in, printer, REPEATS, true);
+
+        System.setErr(origErr);
+        Assert.assertEquals(repeat(concat(expectedOutput), REPEATS), new String(out.toByteArray()));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/AddTest.java	Fri Dec 21 10:45:37 2012 -0800
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.sl.test;
+
+import org.junit.*;
+
+public class AddTest extends AbstractTest {
+
+    private static String[] INPUT = new String[] {
+"function main {  ",
+"  print 3 + 4;  ",
+"  print 3 + \"4\";  ",
+"  print \"3\" + 4;  ",
+"  print \"3\" + \"4\";  ",
+"  print 3 + 4000000000000;  ",
+"  print 3000000000000 + 4;  ",
+"  print 3000000000000 + 4000000000000;  ",
+"}  ",
+    };
+
+    private static String[] OUTPUT = new String[] {
+"7",
+"34",
+"34",
+"34",
+"4000000000003",
+"3000000000004",
+"7000000000000",
+    };
+
+    @Test
+    public void test() {
+        executeSL(INPUT, OUTPUT, true);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/ComparisonTest.java	Fri Dec 21 10:45:37 2012 -0800
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.sl.test;
+
+import org.junit.*;
+
+public class ComparisonTest extends AbstractTest {
+
+    private static String[] INPUT = new String[] {
+"function main {  ",
+"  print 4 < 20;  ",
+"  print 4 < \"20\";  ",
+"  print \"4\" < 20;  ",
+"  print \"4\" < \"20\";  ",
+"  print 4 < 20000000000000;  ",
+"  print 4000000000000 < 20;  ",
+"  print 4000000000000 < 20000000000000;  ",
+"}  ",
+    };
+
+    private static String[] OUTPUT = new String[] {
+"true",
+"false",
+"false",
+"false",
+"true",
+"false",
+"true",
+    };
+
+    @Test
+    public void test() {
+        executeSL(INPUT, OUTPUT, true);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/LoopPrintTest.java	Fri Dec 21 10:45:37 2012 -0800
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.sl.test;
+
+import org.junit.*;
+
+public class LoopPrintTest extends AbstractTest {
+
+    private static String[] INPUT = new String[] {
+"function main {  ",
+"  i = 0;  ",
+"  while (i < 1000) {  ",
+"    i = i + 1;  ",
+"  }  ",
+"  print i;  ",
+"}  ",
+    };
+
+    private static String[] OUTPUT = new String[] {
+"1000",
+    };
+
+    @Test
+    public void test() {
+        executeSL(INPUT, OUTPUT, true);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/LoopTest.java	Fri Dec 21 10:45:37 2012 -0800
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.sl.test;
+
+import org.junit.*;
+
+public class LoopTest extends AbstractTest {
+
+    private static String[] INPUT = new String[] {
+"function main {  ",
+"  i = 0;  ",
+"  while (i < 1000) {  ",
+"    i = i + 1;  ",
+"  }  ",
+"  return i;  ",
+"}  ",
+    };
+
+    private static String[] OUTPUT = new String[] {
+"1000",
+    };
+
+    @Test
+    public void test() {
+        executeSL(INPUT, OUTPUT, true);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/MulTest.java	Fri Dec 21 10:45:37 2012 -0800
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.sl.test;
+
+import org.junit.*;
+
+public class MulTest extends AbstractTest {
+
+    private static String[] INPUT = new String[] {
+"function main {  ",
+"  print 3 * 4;  ",
+"  print 3 * 4000000000000;  ",
+"  print 3000000000000 * 4;  ",
+"  print 3000000000000 * 4000000000000;  ",
+"}  ",
+    };
+
+    private static String[] OUTPUT = new String[] {
+"12",
+"12000000000000",
+"12000000000000",
+"12000000000000000000000000",
+    };
+
+    @Test
+    public void test() {
+        executeSL(INPUT, OUTPUT, true);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SplitOutputStream.java	Fri Dec 21 10:45:37 2012 -0800
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.sl.test;
+
+import java.io.*;
+
+public class SplitOutputStream extends OutputStream {
+
+    private final OutputStream[] outputs;
+
+    public SplitOutputStream(OutputStream... outputs) {
+        this.outputs = outputs;
+    }
+
+    @Override
+    public void write(int b) throws IOException {
+        for (OutputStream out : outputs) {
+            out.write(b);
+        }
+    }
+
+    @Override
+    public void write(byte[] b) throws IOException {
+        for (OutputStream out : outputs) {
+            out.write(b);
+        }
+    }
+
+    @Override
+    public void write(byte[] b, int off, int len) throws IOException {
+        for (OutputStream out : outputs) {
+            out.write(b, off, len);
+        }
+    }
+
+    @Override
+    public void flush() throws IOException {
+        for (OutputStream out : outputs) {
+            out.flush();
+        }
+    }
+
+    @Override
+    public void close() throws IOException {
+        for (OutputStream out : outputs) {
+            out.close();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SumTest.java	Fri Dec 21 10:45:37 2012 -0800
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.sl.test;
+
+import org.junit.*;
+
+public class SumTest extends AbstractTest {
+
+    private static String[] INPUT = new String[] {
+"function main {  ",
+"  i = 0;  ",
+"  sum = 0;  ",
+"  while (i < 1000) {  ",
+"    sum = sum + 100000000;  ",
+"    i = i + 1;  ",
+"  }  ",
+"  return sum;  ",
+"}  ",
+    };
+
+    private static String[] OUTPUT = new String[] {
+"100000000000",
+    };
+
+    @Test
+    public void test() {
+        executeSL(INPUT, OUTPUT, true);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/NodeFactory.java	Fri Dec 21 10:45:37 2012 -0800
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.sl;
+
+import java.io.*;
+import java.math.*;
+import java.util.*;
+
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.sl.nodes.*;
+import com.oracle.truffle.sl.ops.*;
+import com.oracle.truffle.sl.types.*;
+
+public class NodeFactory {
+
+    private final HashMap<String, FunctionDefinitionNode> functions;
+    private final PrintStream printOutput;
+
+    private FrameDescriptor frameDescriptor;
+    private TypedNode returnValue;
+
+    public NodeFactory(PrintStream printOutput) {
+        this.functions = new HashMap<>();
+        this.printOutput = printOutput;
+    }
+
+    public FunctionDefinitionNode findFunction(String name) {
+        return functions.get(name);
+    }
+
+    public void startFunction() {
+        frameDescriptor = new FrameDescriptor(TypesGen.TYPES);
+    }
+
+    public void createFunction(StatementNode body, String name) {
+        functions.put(name, new FunctionDefinitionNode(body, frameDescriptor, name, returnValue));
+    }
+
+    public TypedNode createLocal(String name) {
+        return ReadLocalOpFactory.create(frameDescriptor.findOrAddFrameSlot(name));
+    }
+
+    public TypedNode createStringLiteral(String value) {
+        return StringLiteralFactory.create(value);
+    }
+
+    public StatementNode createAssignment(String name, TypedNode right) {
+        return WriteLocalOpFactory.create(right, frameDescriptor.findOrAddFrameSlot(name));
+    }
+
+    public StatementNode createPrint(List<TypedNode> expressions) {
+        return new PrintNode(expressions, printOutput);
+    }
+
+    public StatementNode createWhile(ConditionNode condition, StatementNode body) {
+        return new WhileNode(condition, body);
+    }
+
+    public StatementNode createBlock(List<StatementNode> statements) {
+        return new BlockNode(statements.toArray(new StatementNode[statements.size()]));
+    }
+
+    public TypedNode createBinary(String operation, TypedNode left, TypedNode right) {
+        switch (operation) {
+            case "+":
+                return AddOpFactory.create(left, right);
+            case "*":
+                return MulOpFactory.create(left, right);
+            case "<":
+                return LessThanOpFactory.create(left, right);
+            case "&&":
+                return LogicalAndOpFactory.create(left, right);
+            default:
+                throw new RuntimeException("unexpected operation: " + operation);
+        }
+    }
+
+    public TypedNode createNumericLiteral(String value) {
+        try {
+            return IntegerLiteralFactory.create(Integer.parseInt(value));
+        } catch (NumberFormatException ex) {
+            return BigIntegerLiteralFactory.create(new BigInteger(value));
+        }
+    }
+
+    public TypedNode createTime() {
+        return TimeOpFactory.create();
+    }
+
+    public StatementNode createReturn(TypedNode value) {
+        FrameSlot slot = frameDescriptor.findOrAddFrameSlot("<retval>");
+        if (returnValue == null) {
+            returnValue = ReadLocalOpFactory.create(slot);
+        }
+        StatementNode write = WriteLocalOpFactory.create(value, slot);
+        return new ReturnNode(write);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLArguments.java	Fri Dec 21 10:45:37 2012 -0800
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.sl;
+
+import com.oracle.truffle.api.*;
+
+public final class SLArguments extends Arguments {
+
+    public final Object[] arguments;
+
+    public SLArguments(Object[] arguments) {
+        this.arguments = arguments;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SimpleLanguage.java	Fri Dec 21 10:45:37 2012 -0800
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.sl;
+
+import java.io.*;
+
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.sl.nodes.*;
+import com.oracle.truffle.sl.parser.*;
+import com.oracle.truffle.sl.tools.*;
+
+public class SimpleLanguage {
+
+    public static void main(String[] args) throws IOException {
+        run(new FileInputStream(args[0]), System.out, 10, true);
+    }
+
+    public static void run(InputStream input, PrintStream printOutput, int repeats, boolean log) {
+        System.out.printf("== running on %s\n", Truffle.getRuntime().getName());
+
+        NodeFactory factory = new NodeFactory(printOutput);
+
+        Parser parser = new Parser(new Scanner(input), factory);
+        parser.Parse();
+
+        FunctionDefinitionNode rootNode = factory.findFunction("main");
+        if (log) {
+            GraphPrinter.print(rootNode);
+        }
+
+        try {
+            CallTarget function = Truffle.getRuntime().createCallTarget(rootNode, rootNode.getFrameDescriptor());
+            for (int i = 0; i < repeats; i++) {
+                Arguments arguments = new SLArguments(new Object[0]);
+
+                long start = System.nanoTime();
+                Object result = function.call(null, arguments);
+                long end = System.nanoTime();
+
+                if (result != null) {
+                    printOutput.println(result);
+                }
+                if (log) {
+                    System.out.printf("== iteration %d: %.3f ms\n", (i + 1), (end - start) / 1000000.0);
+                }
+            }
+
+        } finally {
+            if (log) {
+                GraphPrinter.print(rootNode);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/BlockNode.java	Fri Dec 21 10:45:37 2012 -0800
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.sl.nodes;
+
+import com.oracle.truffle.api.frame.*;
+
+public class BlockNode extends StatementNode {
+
+    @Children
+    private final StatementNode[] statements;
+
+    public BlockNode(StatementNode[] statements) {
+        this.statements = adoptChildren(statements);
+    }
+
+    @Override
+    public void executeVoid(VirtualFrame frame) {
+        for (StatementNode statement : statements) {
+            statement.executeVoid(frame);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/BreakException.java	Fri Dec 21 10:45:37 2012 -0800
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.sl.nodes;
+
+public final class BreakException extends ControlFlowException {
+
+    private static final long serialVersionUID = -91013036379258890L;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/BreakNode.java	Fri Dec 21 10:45:37 2012 -0800
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.sl.nodes;
+
+import com.oracle.truffle.api.frame.*;
+
+public final class BreakNode extends StatementNode {
+
+    private final BreakException target;
+
+    public BreakNode(BreakException target) {
+        this.target = target;
+    }
+
+    @Override
+    public void executeVoid(VirtualFrame frame) {
+        throw target;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ConditionNode.java	Fri Dec 21 10:45:37 2012 -0800
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.sl.nodes;
+
+import com.oracle.truffle.api.frame.*;
+
+public abstract class ConditionNode extends StatementNode {
+
+    public abstract boolean executeCondition(VirtualFrame frame);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ContinueException.java	Fri Dec 21 10:45:37 2012 -0800
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.sl.nodes;
+
+public final class ContinueException extends ControlFlowException {
+
+    private static final long serialVersionUID = 5329687983726237188L;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ContinueNode.java	Fri Dec 21 10:45:37 2012 -0800
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.sl.nodes;
+
+import com.oracle.truffle.api.frame.*;
+
+public final class ContinueNode extends StatementNode {
+
+    private final ContinueException target;
+
+    public ContinueNode(ContinueException target) {
+        this.target = target;
+    }
+
+    @Override
+    public void executeVoid(VirtualFrame frame) {
+        throw target;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ControlFlowException.java	Fri Dec 21 10:45:37 2012 -0800
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.sl.nodes;
+
+/**
+ * Common base class for exceptions that are used to implement control flow.
+ */
+public abstract class ControlFlowException extends RuntimeException {
+
+    private static final long serialVersionUID = 4924673852577649008L;
+
+    @SuppressWarnings("all")
+    @Override
+    public final Throwable fillInStackTrace() {
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/FunctionDefinitionNode.java	Fri Dec 21 10:45:37 2012 -0800
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.sl.nodes;
+
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.sl.types.*;
+
+public class FunctionDefinitionNode extends RootNode {
+
+    private final FrameDescriptor frameDescriptor;
+    private final String name;
+    @Child
+    private StatementNode body;
+    @Child
+    private TypedNode returnValue;
+
+    public FunctionDefinitionNode(StatementNode body, FrameDescriptor frameDescriptor, String name, TypedNode returnValue) {
+        this.body = adoptChild(body);
+        this.frameDescriptor = frameDescriptor;
+        this.name = name;
+        this.returnValue = adoptChild(returnValue);
+    }
+
+    @Override
+    public Object execute(VirtualFrame frame) {
+        try {
+            body.executeVoid(frame);
+        } catch (ReturnException ex) {
+            // Nothing to do, we just need to return.
+        }
+        if (returnValue != null) {
+            return returnValue.executeGeneric(frame);
+        } else {
+            return null;
+        }
+    }
+
+    public FrameDescriptor getFrameDescriptor() {
+        return frameDescriptor;
+    }
+
+    @Override
+    public String toString() {
+        return "Function " + name + "@" + Integer.toHexString(hashCode());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/IfNode.java	Fri Dec 21 10:45:37 2012 -0800
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.sl.nodes;
+
+import com.oracle.truffle.api.frame.*;
+
+public class IfNode extends StatementNode {
+
+    @Child
+    private ConditionNode condition;
+    @Child
+    private StatementNode thenPart;
+    @Child
+    private StatementNode elsePart;
+
+    public IfNode(ConditionNode condition, StatementNode thenPart, StatementNode elsePart) {
+        this.condition = adoptChild(condition);
+        this.thenPart = adoptChild(thenPart);
+        this.elsePart = adoptChild(elsePart);
+    }
+
+    @Override
+    public void executeVoid(VirtualFrame frame) {
+        if (condition.executeCondition(frame)) {
+            thenPart.executeVoid(frame);
+        } else if (elsePart != null) {
+            elsePart.executeVoid(frame);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/PrintNode.java	Fri Dec 21 10:45:37 2012 -0800
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.sl.nodes;
+
+import java.io.*;
+import java.util.*;
+
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.sl.types.*;
+
+public class PrintNode extends StatementNode {
+
+    @Children
+    private final TypedNode[] expressions;
+
+    private final PrintStream output;
+
+    public PrintNode(List<TypedNode> expressions, PrintStream output) {
+        this.expressions = adoptChildren(expressions.toArray(new TypedNode[expressions.size()]));
+        this.output = output;
+    }
+
+    @ExplodeLoop
+    @Override
+    public void executeVoid(VirtualFrame frame) {
+        for (TypedNode expression : expressions) {
+            output.print(expression.executeGeneric(frame));
+        }
+        output.println();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ReturnException.java	Fri Dec 21 10:45:37 2012 -0800
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.sl.nodes;
+
+public final class ReturnException extends ControlFlowException {
+
+    private static final long serialVersionUID = 4073191346281369231L;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ReturnNode.java	Fri Dec 21 10:45:37 2012 -0800
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.sl.nodes;
+
+import com.oracle.truffle.api.frame.*;
+
+public class ReturnNode extends StatementNode {
+
+    private static final ReturnException EXCEPTION = new ReturnException();
+
+    @Child
+    private StatementNode expr;
+
+    public ReturnNode(StatementNode expr) {
+        this.expr = adoptChild(expr);
+    }
+
+    @Override
+    public void executeVoid(VirtualFrame frame) {
+        expr.executeVoid(frame);
+        throw EXCEPTION;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/StatementNode.java	Fri Dec 21 10:45:37 2012 -0800
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.sl.nodes;
+
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.nodes.*;
+
+public abstract class StatementNode extends Node {
+
+    public abstract void executeVoid(VirtualFrame frame);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/WhileNode.java	Fri Dec 21 10:45:37 2012 -0800
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.sl.nodes;
+
+import com.oracle.truffle.api.frame.*;
+
+public class WhileNode extends StatementNode {
+
+    @Child
+    private ConditionNode condition;
+    @Child
+    private StatementNode body;
+
+    private final BreakException breakTarget;
+    private final ContinueException continueTarget;
+
+    public WhileNode(ConditionNode condition, StatementNode body) {
+        this.condition = adoptChild(condition);
+        this.body = adoptChild(body);
+
+        this.breakTarget = new BreakException();
+        this.continueTarget = new ContinueException();
+    }
+
+    @Override
+    public void executeVoid(VirtualFrame frame) {
+        try {
+            while (condition.executeCondition(frame)) {
+                try {
+                    body.executeVoid(frame);
+                } catch (ContinueException ex) {
+                    if (ex != continueTarget) {
+                        throw ex;
+                    }
+                    // Fall through to next loop iteration.
+                }
+            }
+        } catch (BreakException ex) {
+            if (ex != breakTarget) {
+                throw ex;
+            }
+            // Done executing this loop, exit method to execute statement following the loop.
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/ops/AddOp.java	Fri Dec 21 10:45:37 2012 -0800
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.sl.ops;
+
+import java.math.*;
+
+import com.oracle.truffle.api.codegen.*;
+import com.oracle.truffle.api.intrinsics.*;
+import com.oracle.truffle.sl.types.*;
+
+@Operation(typeSystem = Types.class, values = {"left", "right"})
+public class AddOp {
+
+    @Specialization
+    @SpecializationThrows(javaClass = ArithmeticException.class, transitionTo = "doBigInteger")
+    public int doInteger(int left, int right) {
+        return ExactMath.addExact(left, right);
+    }
+
+    @Specialization
+    public BigInteger doBigInteger(BigInteger left, BigInteger right) {
+        return left.add(right);
+    }
+
+    @Specialization
+    public String doStringDirect(String left, String right) {
+        return left + right;
+    }
+
+    @Specialization
+    @SpecializationGuard(methodName = "isString")
+    public String doString(Object left, Object right) {
+        return left.toString() + right.toString();
+    }
+
+    @Generic
+    public Object doGeneric(Object left, Object right) {
+        throw new RuntimeException("addition not defined for types " + left.getClass().getSimpleName() + ", " + right.getClass().getSimpleName());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/ops/BigIntegerLiteral.java	Fri Dec 21 10:45:37 2012 -0800
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.sl.ops;
+
+import java.math.*;
+
+import com.oracle.truffle.api.codegen.*;
+import com.oracle.truffle.sl.types.*;
+
+@Operation(typeSystem = Types.class)
+public class BigIntegerLiteral {
+
+    private final BigInteger value;
+
+    public BigIntegerLiteral(BigInteger value) {
+        this.value = value;
+    }
+
+    @Specialization
+    public BigInteger doBigInteger() {
+        return value;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/ops/IfOp.java	Fri Dec 21 10:45:37 2012 -0800
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.sl.ops;
+
+import java.math.*;
+
+import com.oracle.truffle.api.codegen.*;
+import com.oracle.truffle.sl.types.*;
+
+@SuppressWarnings("unused")
+@Operation(typeSystem = Types.class, values = {"condition"}, shortCircuitValues = {"ifPart", "elsePart"})
+public class IfOp {
+
+    @ShortCircuit("ifPart")
+    public boolean needsIfPart(boolean condition) {
+        return condition;
+    }
+
+    @ShortCircuit("ifPart")
+    public boolean needsIfPart(Object condition) {
+        if (TypesGen.TYPES.isBoolean(condition)) {
+            return TypesGen.TYPES.asBoolean(condition);
+        }
+        throw new RuntimeException("operation not defined for type " + condition.getClass().getSimpleName());
+    }
+
+    @ShortCircuit("elsePart")
+    public boolean needsElsePart(Object condition, boolean hasIfPart, Object ifPart) {
+        return !hasIfPart;
+    }
+
+    @ShortCircuit("elsePart")
+    public boolean needsElsePart(boolean condition, boolean hasIfPart, int ifPart) {
+        return !hasIfPart;
+    }
+
+    @ShortCircuit("elsePart")
+    public boolean needsElsePart(boolean condition, boolean hasIfPart, BigInteger ifPart) {
+        return !hasIfPart;
+    }
+
+    @Specialization
+    public int doInteger(boolean condition, boolean hasIfPart, int ifPart, boolean hasElsePart, int elsePart) {
+        return hasIfPart ? ifPart : elsePart;
+    }
+
+    @Specialization
+    public BigInteger doBigInteger(boolean condition, boolean hasIfPart, BigInteger ifPart, boolean hasElsePart, BigInteger elsePart) {
+        return hasIfPart ? ifPart : elsePart;
+    }
+
+    @Generic
+    public Object doGeneric(Object condition, boolean hasIfPart, Object ifPart, boolean hasElsePart, Object elsePart) {
+        return hasIfPart ? ifPart : elsePart;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/ops/IntegerLiteral.java	Fri Dec 21 10:45:37 2012 -0800
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.sl.ops;
+
+import com.oracle.truffle.api.codegen.*;
+import com.oracle.truffle.sl.types.*;
+
+@Operation(typeSystem = Types.class)
+public class IntegerLiteral {
+
+    private final int value;
+
+    public IntegerLiteral(int value) {
+        this.value = value;
+    }
+
+    @Specialization
+    protected int doInteger() {
+        return this.value;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/ops/LessThanOp.java	Fri Dec 21 10:45:37 2012 -0800
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.sl.ops;
+
+import java.math.*;
+
+import com.oracle.truffle.api.codegen.*;
+import com.oracle.truffle.sl.types.*;
+
+@Operation(typeSystem = Types.class, values = {"left", "right"})
+public class LessThanOp {
+
+    @Specialization
+    public boolean doInteger(int left, int right) {
+        return left < right;
+    }
+
+    @Specialization
+    public boolean doBigInteger(BigInteger left, BigInteger right) {
+        return left.compareTo(right) < 0;
+    }
+
+    @Specialization
+    @SpecializationGuard(methodName = "isString")
+    public boolean doString(Object left, Object right) {
+        return left.toString().compareTo(right.toString()) < 0;
+    }
+
+    @Generic
+    public boolean doGeneric(Object left, Object right) {
+        throw new RuntimeException("comparison not defined for types " + left.getClass().getSimpleName() + ", " + right.getClass().getSimpleName());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/ops/LogicalAndOp.java	Fri Dec 21 10:45:37 2012 -0800
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.sl.ops;
+
+import com.oracle.truffle.api.codegen.*;
+import com.oracle.truffle.sl.types.*;
+
+@SuppressWarnings("unused")
+@Operation(typeSystem = Types.class, values = {"left"}, shortCircuitValues = {"right"})
+public class LogicalAndOp {
+
+    @ShortCircuit(value = "right")
+    public boolean needsRight(boolean left) {
+        return left;
+    }
+
+    @ShortCircuit(value = "right")
+    public boolean needsRight(Object left) {
+        return TypesGen.TYPES.asBoolean(left);
+    }
+
+    @Specialization
+    public boolean doBoolean(boolean left, boolean hasRight, boolean right) {
+        return hasRight && right;
+    }
+
+    @Generic
+    public Object doGeneric(Object left, boolean hasRight, Object right) {
+        throw new RuntimeException("operation not defined for type " + left.getClass().getSimpleName());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/ops/MulOp.java	Fri Dec 21 10:45:37 2012 -0800
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.sl.ops;
+
+import java.math.*;
+
+import com.oracle.truffle.api.codegen.*;
+import com.oracle.truffle.api.intrinsics.*;
+import com.oracle.truffle.sl.types.*;
+
+@Operation(typeSystem = Types.class, values = {"left", "right"})
+public class MulOp {
+
+    @Specialization
+    @SpecializationThrows(javaClass = ArithmeticException.class, transitionTo = "doBigInteger")
+    public int doInteger(int left, int right) {
+        return ExactMath.multiplyExact(left, right);
+    }
+
+    @Specialization
+    public BigInteger doBigInteger(BigInteger left, BigInteger right) {
+        return left.multiply(right);
+    }
+
+    @Generic
+    public Object doGeneric(Object left, Object right) {
+        throw new RuntimeException("multiplication not defined for types " + left.getClass().getSimpleName() + ", " + right.getClass().getSimpleName());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/ops/ReadLocalOp.java	Fri Dec 21 10:45:37 2012 -0800
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.sl.ops;
+
+import java.math.*;
+
+import com.oracle.truffle.api.codegen.*;
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.sl.types.*;
+
+@Operation(typeSystem = Types.class, baseClass = FrameSlotNode.class)
+public class ReadLocalOp {
+
+    @Specialization(order = 2)
+    public int doInteger(VirtualFrame frame, FrameSlot slot) {
+        return frame.getInt(slot);
+    }
+
+    @Specialization
+    public BigInteger doBigInteger(VirtualFrame frame, FrameSlot slot) {
+        return (BigInteger) frame.getObject(slot);
+    }
+
+    @Specialization
+    public boolean doBoolean(VirtualFrame frame, FrameSlot slot) {
+        return frame.getBoolean(slot);
+    }
+
+    @Specialization
+    public String doString(VirtualFrame frame, FrameSlot slot) {
+        return (String) frame.getObject(slot);
+    }
+
+    @Generic
+    public Object doGeneric(VirtualFrame frame, FrameSlot slot) {
+        return frame.getObject(slot);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/ops/StringLiteral.java	Fri Dec 21 10:45:37 2012 -0800
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.sl.ops;
+
+import com.oracle.truffle.api.codegen.*;
+import com.oracle.truffle.sl.types.*;
+
+@Operation(typeSystem = Types.class)
+public class StringLiteral {
+
+    private final String value;
+
+    public StringLiteral(String value) {
+        this.value = value;
+    }
+
+    @Specialization
+    protected String doString() {
+        return value;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/ops/TimeOp.java	Fri Dec 21 10:45:37 2012 -0800
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.sl.ops;
+
+import com.oracle.truffle.api.codegen.*;
+import com.oracle.truffle.sl.types.*;
+
+@Operation(typeSystem = Types.class, baseClass = TypedNode.class)
+public class TimeOp {
+
+    public static final long START_TIME = System.currentTimeMillis();
+
+    @Specialization
+    public int doInt() {
+        return (int) (System.currentTimeMillis() - START_TIME);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/ops/WriteLocalOp.java	Fri Dec 21 10:45:37 2012 -0800
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.sl.ops;
+
+import java.math.*;
+
+import com.oracle.truffle.api.codegen.*;
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.sl.types.*;
+
+@Operation(typeSystem = Types.class, baseClass = FrameSlotNode.class, values = "right")
+public class WriteLocalOp {
+
+    @Specialization
+    public int doInteger(VirtualFrame frame, int right, FrameSlot slot) {
+        frame.setInt(slot, right);
+        return right;
+    }
+
+    @Specialization
+    public BigInteger doBigInteger(VirtualFrame frame, BigInteger right, FrameSlot slot) {
+        frame.setObject(slot, right);
+        return right;
+    }
+
+    @Specialization
+    public boolean doBoolean(VirtualFrame frame, boolean right, FrameSlot slot) {
+        frame.setBoolean(slot, right);
+        return right;
+    }
+
+    @Specialization
+    public String doString(VirtualFrame frame, String right, FrameSlot slot) {
+        frame.setObject(slot, right);
+        return right;
+    }
+
+    @Generic
+    public Object doGeneric(VirtualFrame frame, Object right, FrameSlot slot) {
+        frame.setObject(slot, right);
+        return right;
+    }
+
+    @SpecializationListener
+    protected void onSpecialize(VirtualFrame frame, Object value, FrameSlot slot) {
+        slot.setType(value.getClass());
+        frame.updateToLatestVersion();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Copyright.frame	Fri Dec 21 10:45:37 2012 -0800
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ // The content of this file is automatically generated. DO NOT EDIT.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Parser.frame	Fri Dec 21 10:45:37 2012 -0800
@@ -0,0 +1,212 @@
+/*-------------------------------------------------------------------------
+Compiler Generator Coco/R,
+Copyright (c) 1990, 2004 Hanspeter Moessenboeck, University of Linz
+extended by M. Loeberbauer & A. Woess, Univ. of Linz
+ported from C# to Java by Wolfgang Ahorner
+with improvements by Pat Terry, Rhodes University
+
+This program is free software; you can redistribute it and/or modify it 
+under the terms of the GNU General Public License as published by the 
+Free Software Foundation; either version 2, or (at your option) any 
+later version.
+
+This program is distributed in the hope that it will be useful, but 
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
+or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+for more details.
+
+You should have received a copy of the GNU General Public License along 
+with this program; if not, write to the Free Software Foundation, Inc., 
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As an exception, it is allowed to write an extension of Coco/R that is
+used as a plugin in non-free software.
+
+If not otherwise stated, any source code generated by Coco/R (other than 
+Coco/R itself) does not fall under the GNU General Public License.
+------------------------------------------------------------------------*/
+-->begin
+import java.util.*;
+
+import com.oracle.truffle.sl.*;
+import com.oracle.truffle.sl.nodes.*;
+import com.oracle.truffle.sl.types.*;
+
+// Checkstyle: stop
+public class Parser {
+-->constants
+    static final boolean T = true;
+    static final boolean x = false;
+    static final int minErrDist = 2;
+
+    public Token t; // last recognized token
+    public Token la; // lookahead token
+    int errDist = minErrDist;
+
+    public final Scanner scanner;
+    public final Errors errors;
+    private final NodeFactory factory;
+	-->declarations
+    public Parser(Scanner scanner, NodeFactory factory) {
+        this.scanner = scanner;
+        this.factory = factory;
+        errors = new Errors();
+    }
+
+    void SynErr(int n) {
+        if (errDist >= minErrDist)
+            errors.SynErr(la.line, la.col, n);
+        errDist = 0;
+    }
+
+    public void SemErr(String msg) {
+        if (errDist >= minErrDist)
+            errors.SemErr(t.line, t.col, msg);
+        errDist = 0;
+    }
+
+    void Get() {
+        for (;;) {
+            t = la;
+            la = scanner.Scan();
+            if (la.kind <= maxT) {
+                ++errDist;
+                break;
+            }
+-->pragmas
+            la = t;
+        }
+    }
+
+    void Expect(int n) {
+        if (la.kind == n)
+            Get();
+        else {
+            SynErr(n);
+        }
+    }
+
+    boolean StartOf(int s) {
+        return set[s][la.kind];
+    }
+
+    void ExpectWeak(int n, int follow) {
+        if (la.kind == n)
+            Get();
+        else {
+            SynErr(n);
+            while (!StartOf(follow))
+                Get();
+        }
+    }
+
+    boolean WeakSeparator(int n, int syFol, int repFol) {
+        int kind = la.kind;
+        if (kind == n) {
+            Get();
+            return true;
+        } else if (StartOf(repFol))
+            return false;
+        else {
+            SynErr(n);
+            while (!(set[syFol][kind] || set[repFol][kind] || set[0][kind])) {
+                Get();
+                kind = la.kind;
+            }
+            return StartOf(syFol);
+        }
+    }
+
+-->productions
+
+    public void Parse() {
+        la = new Token();
+        la.val = "";
+        Get();
+-->parseRoot
+    }
+
+    private static final boolean[][] set = {
+-->initialization
+    };
+
+    public String ParseErrors() {
+        java.io.PrintStream oldStream = System.out;
+
+        java.io.OutputStream out = new java.io.ByteArrayOutputStream();
+        java.io.PrintStream newStream = new java.io.PrintStream(out);
+
+        errors.errorStream = newStream;
+
+        Parse();
+
+        String errorStream = out.toString();
+        errors.errorStream = oldStream;
+
+        return errorStream;
+
+    }
+} // end Parser
+
+class Errors {
+
+    public int count = 0; // number of errors detected
+    public java.io.PrintStream errorStream = System.out; // error messages go to this stream
+    public String errMsgFormat = "-- line {0} col {1}: {2}"; // 0=line, 1=column, 2=text
+
+    protected void printMsg(int line, int column, String msg) {
+        StringBuffer b = new StringBuffer(errMsgFormat);
+        int pos = b.indexOf("{0}");
+        if (pos >= 0) {
+            b.delete(pos, pos + 3);
+            b.insert(pos, line);
+        }
+        pos = b.indexOf("{1}");
+        if (pos >= 0) {
+            b.delete(pos, pos + 3);
+            b.insert(pos, column);
+        }
+        pos = b.indexOf("{2}");
+        if (pos >= 0)
+            b.replace(pos, pos + 3, msg);
+        errorStream.println(b.toString());
+    }
+
+    public void SynErr(int line, int col, int n) {
+        String s;
+        switch (n) {-->errors
+            default:
+                s = "error " + n;
+                break;
+        }
+        printMsg(line, col, s);
+        count++;
+    }
+
+    public void SemErr(int line, int col, String s) {
+        printMsg(line, col, s);
+        count++;
+    }
+
+    public void SemErr(String s) {
+        errorStream.println(s);
+        count++;
+    }
+
+    public void Warning(int line, int col, String s) {
+        printMsg(line, col, s);
+    }
+
+    public void Warning(String s) {
+        errorStream.println(s);
+    }
+} // Errors
+
+class FatalError extends RuntimeException {
+
+    public static final long serialVersionUID = 1L;
+
+    public FatalError(String s) {
+        super(s);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Parser.java	Fri Dec 21 10:45:37 2012 -0800
@@ -0,0 +1,453 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ // The content of this file is automatically generated. DO NOT EDIT.
+
+package com.oracle.truffle.sl.parser;
+import java.util.*;
+
+import com.oracle.truffle.sl.*;
+import com.oracle.truffle.sl.nodes.*;
+import com.oracle.truffle.sl.types.*;
+
+// Checkstyle: stop
+public class Parser {
+	public static final int _EOF = 0;
+	public static final int _identifier = 1;
+	public static final int _stringLiteral = 2;
+	public static final int _numericLiteral = 3;
+	public static final int maxT = 25;
+
+    static final boolean T = true;
+    static final boolean x = false;
+    static final int minErrDist = 2;
+
+    public Token t; // last recognized token
+    public Token la; // lookahead token
+    int errDist = minErrDist;
+
+    public final Scanner scanner;
+    public final Errors errors;
+    private final NodeFactory factory;
+	
+    public Parser(Scanner scanner, NodeFactory factory) {
+        this.scanner = scanner;
+        this.factory = factory;
+        errors = new Errors();
+    }
+
+    void SynErr(int n) {
+        if (errDist >= minErrDist)
+            errors.SynErr(la.line, la.col, n);
+        errDist = 0;
+    }
+
+    public void SemErr(String msg) {
+        if (errDist >= minErrDist)
+            errors.SemErr(t.line, t.col, msg);
+        errDist = 0;
+    }
+
+    void Get() {
+        for (;;) {
+            t = la;
+            la = scanner.Scan();
+            if (la.kind <= maxT) {
+                ++errDist;
+                break;
+            }
+
+            la = t;
+        }
+    }
+
+    void Expect(int n) {
+        if (la.kind == n)
+            Get();
+        else {
+            SynErr(n);
+        }
+    }
+
+    boolean StartOf(int s) {
+        return set[s][la.kind];
+    }
+
+    void ExpectWeak(int n, int follow) {
+        if (la.kind == n)
+            Get();
+        else {
+            SynErr(n);
+            while (!StartOf(follow))
+                Get();
+        }
+    }
+
+    boolean WeakSeparator(int n, int syFol, int repFol) {
+        int kind = la.kind;
+        if (kind == n) {
+            Get();
+            return true;
+        } else if (StartOf(repFol))
+            return false;
+        else {
+            SynErr(n);
+            while (!(set[syFol][kind] || set[repFol][kind] || set[0][kind])) {
+                Get();
+                kind = la.kind;
+            }
+            return StartOf(syFol);
+        }
+    }
+
+	void SimpleLanguage() {
+		Function();
+		while (la.kind == 4) {
+			Function();
+		}
+	}
+
+	void Function() {
+		Expect(4);
+		factory.startFunction(); 
+		Expect(1);
+		String name = t.val; 
+		StatementNode body = Block();
+		factory.createFunction(body, name); 
+	}
+
+	StatementNode  Block() {
+		StatementNode  result;
+		List<StatementNode> statements = new ArrayList<>(); 
+		Expect(5);
+		while (StartOf(1)) {
+			StatementNode statement = Statement();
+			statements.add(statement); 
+		}
+		Expect(6);
+		result = factory.createBlock(statements); 
+		return result;
+	}
+
+	StatementNode  Statement() {
+		StatementNode  result;
+		result = null; 
+		if (la.kind == 7) {
+			result = WhileStatement();
+		} else if (la.kind == 1) {
+			result = AssignmentStatement();
+		} else if (la.kind == 12) {
+			result = OutputStatement();
+		} else if (la.kind == 13) {
+			result = ReturnStatement();
+		} else SynErr(26);
+		return result;
+	}
+
+	StatementNode  WhileStatement() {
+		StatementNode  result;
+		Expect(7);
+		Expect(8);
+		ConditionNode condition = Expression();
+		Expect(9);
+		StatementNode body = Block();
+		result = factory.createWhile(condition, body); 
+		return result;
+	}
+
+	StatementNode  AssignmentStatement() {
+		StatementNode  result;
+		Expect(1);
+		String name = t.val; 
+		Expect(10);
+		TypedNode rvalue = Expression();
+		Expect(11);
+		result = factory.createAssignment(name, rvalue); 
+		return result;
+	}
+
+	StatementNode  OutputStatement() {
+		StatementNode  result;
+		List<TypedNode> expressions = new ArrayList<>(); 
+		Expect(12);
+		while (StartOf(2)) {
+			TypedNode value = Expression();
+			expressions.add(value); 
+		}
+		Expect(11);
+		result = factory.createPrint(expressions); 
+		return result;
+	}
+
+	StatementNode  ReturnStatement() {
+		StatementNode  result;
+		Expect(13);
+		TypedNode value = Expression();
+		Expect(11);
+		result = factory.createReturn(value); 
+		return result;
+	}
+
+	TypedNode  Expression() {
+		TypedNode  result;
+		result = ValueExpression();
+		if (StartOf(3)) {
+			switch (la.kind) {
+			case 14: {
+				Get();
+				break;
+			}
+			case 15: {
+				Get();
+				break;
+			}
+			case 16: {
+				Get();
+				break;
+			}
+			case 17: {
+				Get();
+				break;
+			}
+			case 18: {
+				Get();
+				break;
+			}
+			case 19: {
+				Get();
+				break;
+			}
+			}
+			String op = t.val; 
+			TypedNode right = ValueExpression();
+			result = factory.createBinary(op, result, right); 
+		}
+		return result;
+	}
+
+	TypedNode  ValueExpression() {
+		TypedNode  result;
+		result = Term();
+		while (la.kind == 20 || la.kind == 21) {
+			if (la.kind == 20) {
+				Get();
+			} else {
+				Get();
+			}
+			String op = t.val; 
+			TypedNode right = Term();
+			result = factory.createBinary(op, result, right); 
+		}
+		return result;
+	}
+
+	TypedNode  Term() {
+		TypedNode  result;
+		result = Factor();
+		while (la.kind == 22 || la.kind == 23) {
+			if (la.kind == 22) {
+				Get();
+			} else {
+				Get();
+			}
+			String op = t.val; 
+			TypedNode right = Factor();
+			result = factory.createBinary(op, result, right); 
+		}
+		return result;
+	}
+
+	TypedNode  Factor() {
+		TypedNode  result;
+		result = null; 
+		if (la.kind == 24) {
+			result = TimeRef();
+		} else if (la.kind == 1) {
+			result = VariableRef();
+		} else if (la.kind == 2) {
+			result = StringLiteral();
+		} else if (la.kind == 3) {
+			result = NumericLiteral();
+		} else if (la.kind == 8) {
+			Get();
+			result = Expression();
+			Expect(9);
+		} else SynErr(27);
+		return result;
+	}
+
+	TypedNode  TimeRef() {
+		TypedNode  result;
+		Expect(24);
+		result = factory.createTime(); 
+		return result;
+	}
+
+	TypedNode  VariableRef() {
+		TypedNode  result;
+		Expect(1);
+		result = factory.createLocal(t.val); 
+		return result;
+	}
+
+	TypedNode  StringLiteral() {
+		TypedNode  result;
+		Expect(2);
+		result = factory.createStringLiteral(t.val.substring(1, t.val.length() - 1)); 
+		return result;
+	}
+
+	TypedNode  NumericLiteral() {
+		TypedNode  result;
+		Expect(3);
+		result = factory.createNumericLiteral(t.val); 
+		return result;
+	}
+
+
+
+    public void Parse() {
+        la = new Token();
+        la.val = "";
+        Get();
+		SimpleLanguage();
+		Expect(0);
+
+    }
+
+    private static final boolean[][] set = {
+		{T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x},
+		{x,T,x,x, x,x,x,T, x,x,x,x, T,T,x,x, x,x,x,x, x,x,x,x, x,x,x},
+		{x,T,T,T, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x},
+		{x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,T, T,T,T,T, x,x,x,x, x,x,x}
+
+    };
+
+    public String ParseErrors() {
+        java.io.PrintStream oldStream = System.out;
+
+        java.io.OutputStream out = new java.io.ByteArrayOutputStream();
+        java.io.PrintStream newStream = new java.io.PrintStream(out);
+
+        errors.errorStream = newStream;
+
+        Parse();
+
+        String errorStream = out.toString();
+        errors.errorStream = oldStream;
+
+        return errorStream;
+
+    }
+} // end Parser
+
+class Errors {
+
+    public int count = 0; // number of errors detected
+    public java.io.PrintStream errorStream = System.out; // error messages go to this stream
+    public String errMsgFormat = "-- line {0} col {1}: {2}"; // 0=line, 1=column, 2=text
+
+    protected void printMsg(int line, int column, String msg) {
+        StringBuffer b = new StringBuffer(errMsgFormat);
+        int pos = b.indexOf("{0}");
+        if (pos >= 0) {
+            b.delete(pos, pos + 3);
+            b.insert(pos, line);
+        }
+        pos = b.indexOf("{1}");
+        if (pos >= 0) {
+            b.delete(pos, pos + 3);
+            b.insert(pos, column);
+        }
+        pos = b.indexOf("{2}");
+        if (pos >= 0)
+            b.replace(pos, pos + 3, msg);
+        errorStream.println(b.toString());
+    }
+
+    public void SynErr(int line, int col, int n) {
+        String s;
+        switch (n) {
+			case 0: s = "EOF expected"; break;
+			case 1: s = "identifier expected"; break;
+			case 2: s = "stringLiteral expected"; break;
+			case 3: s = "numericLiteral expected"; break;
+			case 4: s = "\"function\" expected"; break;
+			case 5: s = "\"{\" expected"; break;
+			case 6: s = "\"}\" expected"; break;
+			case 7: s = "\"while\" expected"; break;
+			case 8: s = "\"(\" expected"; break;
+			case 9: s = "\")\" expected"; break;
+			case 10: s = "\"=\" expected"; break;
+			case 11: s = "\";\" expected"; break;
+			case 12: s = "\"print\" expected"; break;
+			case 13: s = "\"return\" expected"; break;
+			case 14: s = "\"<\" expected"; break;
+			case 15: s = "\">\" expected"; break;
+			case 16: s = "\"<=\" expected"; break;
+			case 17: s = "\">=\" expected"; break;
+			case 18: s = "\"==\" expected"; break;
+			case 19: s = "\"!=\" expected"; break;
+			case 20: s = "\"+\" expected"; break;
+			case 21: s = "\"-\" expected"; break;
+			case 22: s = "\"*\" expected"; break;
+			case 23: s = "\"/\" expected"; break;
+			case 24: s = "\"time\" expected"; break;
+			case 25: s = "??? expected"; break;
+			case 26: s = "invalid Statement"; break;
+			case 27: s = "invalid Factor"; break;
+            default:
+                s = "error " + n;
+                break;
+        }
+        printMsg(line, col, s);
+        count++;
+    }
+
+    public void SemErr(int line, int col, String s) {
+        printMsg(line, col, s);
+        count++;
+    }
+
+    public void SemErr(String s) {
+        errorStream.println(s);
+        count++;
+    }
+
+    public void Warning(int line, int col, String s) {
+        printMsg(line, col, s);
+    }
+
+    public void Warning(String s) {
+        errorStream.println(s);
+    }
+} // Errors
+
+class FatalError extends RuntimeException {
+
+    public static final long serialVersionUID = 1L;
+
+    public FatalError(String s) {
+        super(s);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Scanner.frame	Fri Dec 21 10:45:37 2012 -0800
@@ -0,0 +1,512 @@
+/*-------------------------------------------------------------------------
+Compiler Generator Coco/R,
+Copyright (c) 1990, 2004 Hanspeter Moessenboeck, University of Linz
+extended by M. Loeberbauer & A. Woess, Univ. of Linz
+ported from C# to Java by Wolfgang Ahorner
+with improvements by Pat Terry, Rhodes University
+
+This program is free software; you can redistribute it and/or modify it 
+under the terms of the GNU General Public License as published by the 
+Free Software Foundation; either version 2, or (at your option) any 
+later version.
+
+This program is distributed in the hope that it will be useful, but 
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
+or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+for more details.
+
+You should have received a copy of the GNU General Public License along 
+with this program; if not, write to the Free Software Foundation, Inc., 
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As an exception, it is allowed to write an extension of Coco/R that is
+used as a plugin in non-free software.
+
+If not otherwise stated, any source code generated by Coco/R (other than 
+Coco/R itself) does not fall under the GNU General Public License.
+------------------------------------------------------------------------*/
+-->begin
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.Map;
+import java.util.HashMap;
+
+// Checkstyle: stop
+class Token {
+
+    public int kind; // token kind
+    public int pos; // token position in bytes in the source text (starting at 0)
+    public int charPos; // token position in characters in the source text (starting at 0)
+    public int col; // token column (starting at 1)
+    public int line; // token line (starting at 1)
+    public String val; // token value
+    public Token next; // ML 2005-03-11 Peek tokens are kept in linked list
+}
+
+// -----------------------------------------------------------------------------------
+// Buffer
+// -----------------------------------------------------------------------------------
+class Buffer {
+
+    // This Buffer supports the following cases:
+    // 1) seekable stream (file)
+    // a) whole stream in buffer
+    // b) part of stream in buffer
+    // 2) non seekable stream (network, console)
+
+    public static final int EOF = Character.MAX_VALUE + 1;
+    private static final int MIN_BUFFER_LENGTH = 1024; // 1KB
+    private static final int MAX_BUFFER_LENGTH = MIN_BUFFER_LENGTH * 64; // 64KB
+    private byte[] buf; // input buffer
+    private int bufStart; // position of first byte in buffer relative to input stream
+    private int bufLen; // length of buffer
+    private int fileLen; // length of input stream (may change if stream is no file)
+    private int bufPos; // current position in buffer
+    private RandomAccessFile file; // input stream (seekable)
+    private InputStream stream; // growing input stream (e.g.: console, network)
+
+    public Buffer(InputStream s) {
+        stream = s;
+        fileLen = bufLen = bufStart = bufPos = 0;
+        buf = new byte[MIN_BUFFER_LENGTH];
+    }
+
+    public Buffer(String fileName) {
+        try {
+            file = new RandomAccessFile(fileName, "r");
+            fileLen = (int) file.length();
+            bufLen = Math.min(fileLen, MAX_BUFFER_LENGTH);
+            buf = new byte[bufLen];
+            bufStart = Integer.MAX_VALUE; // nothing in buffer so far
+            if (fileLen > 0)
+                setPos(0); // setup buffer to position 0 (start)
+            else
+                bufPos = 0; // index 0 is already after the file, thus setPos(0) is invalid
+            if (bufLen == fileLen)
+                Close();
+        } catch (IOException e) {
+            throw new FatalError("Could not open file " + fileName);
+        }
+    }
+
+    // don't use b after this call anymore
+    // called in UTF8Buffer constructor
+    protected Buffer(Buffer b) {
+        buf = b.buf;
+        bufStart = b.bufStart;
+        bufLen = b.bufLen;
+        fileLen = b.fileLen;
+        bufPos = b.bufPos;
+        file = b.file;
+        stream = b.stream;
+        // keep finalize from closing the file
+        b.file = null;
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        super.finalize();
+        Close();
+    }
+
+    protected void Close() {
+        if (file != null) {
+            try {
+                file.close();
+                file = null;
+            } catch (IOException e) {
+                throw new FatalError(e.getMessage());
+            }
+        }
+    }
+
+    public int Read() {
+        if (bufPos < bufLen) {
+            return buf[bufPos++] & 0xff; // mask out sign bits
+        } else if (getPos() < fileLen) {
+            setPos(getPos()); // shift buffer start to pos
+            return buf[bufPos++] & 0xff; // mask out sign bits
+        } else if (stream != null && ReadNextStreamChunk() > 0) {
+            return buf[bufPos++] & 0xff; // mask out sign bits
+        } else {
+            return EOF;
+        }
+    }
+
+    public int Peek() {
+        int curPos = getPos();
+        int ch = Read();
+        setPos(curPos);
+        return ch;
+    }
+
+    // beg .. begin, zero-based, inclusive, in byte
+    // end .. end, zero-based, exclusive, in byte
+    public String GetString(int beg, int end) {
+        int len = 0;
+        char[] buffer = new char[end - beg];
+        int oldPos = getPos();
+        setPos(beg);
+        while (getPos() < end)
+            buffer[len++] = (char) Read();
+        setPos(oldPos);
+        return new String(buffer, 0, len);
+    }
+
+    public int getPos() {
+        return bufPos + bufStart;
+    }
+
+    public void setPos(int value) {
+        if (value >= fileLen && stream != null) {
+            // Wanted position is after buffer and the stream
+            // is not seek-able e.g. network or console,
+            // thus we have to read the stream manually till
+            // the wanted position is in sight.
+            while (value >= fileLen && ReadNextStreamChunk() > 0) {
+                // nothing to do...
+            }
+        }
+
+        if (value < 0 || value > fileLen) {
+            throw new FatalError("buffer out of bounds access, position: " + value);
+        }
+
+        if (value >= bufStart && value < bufStart + bufLen) { // already in buffer
+            bufPos = value - bufStart;
+        } else if (file != null) { // must be swapped in
+            try {
+                file.seek(value);
+                bufLen = file.read(buf);
+                bufStart = value;
+                bufPos = 0;
+            } catch (IOException e) {
+                throw new FatalError(e.getMessage());
+            }
+        } else {
+            // set the position to the end of the file, Pos will return fileLen.
+            bufPos = fileLen - bufStart;
+        }
+    }
+
+    // Read the next chunk of bytes from the stream, increases the buffer
+    // if needed and updates the fields fileLen and bufLen.
+    // Returns the number of bytes read.
+    private int ReadNextStreamChunk() {
+        int free = buf.length - bufLen;
+        if (free == 0) {
+            // in the case of a growing input stream
+            // we can neither seek in the stream, nor can we
+            // foresee the maximum length, thus we must adapt
+            // the buffer size on demand.
+            byte[] newBuf = new byte[bufLen * 2];
+            System.arraycopy(buf, 0, newBuf, 0, bufLen);
+            buf = newBuf;
+            free = bufLen;
+        }
+
+        int read;
+        try {
+            read = stream.read(buf, bufLen, free);
+        } catch (IOException ioex) {
+            throw new FatalError(ioex.getMessage());
+        }
+
+        if (read > 0) {
+            fileLen = bufLen = (bufLen + read);
+            return read;
+        }
+        // end of stream reached
+        return 0;
+    }
+}
+
+// -----------------------------------------------------------------------------------
+// UTF8Buffer
+// -----------------------------------------------------------------------------------
+class UTF8Buffer extends Buffer {
+
+    UTF8Buffer(Buffer b) {
+        super(b);
+    }
+
+    @Override
+    public int Read() {
+        int ch;
+        do {
+            ch = super.Read();
+            // until we find a utf8 start (0xxxxxxx or 11xxxxxx)
+        } while ((ch >= 128) && ((ch & 0xC0) != 0xC0) && (ch != EOF));
+        if (ch < 128 || ch == EOF) {
+            // nothing to do, first 127 chars are the same in ascii and utf8
+            // 0xxxxxxx or end of file character
+        } else if ((ch & 0xF0) == 0xF0) {
+            // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+            int c1 = ch & 0x07;
+            ch = super.Read();
+            int c2 = ch & 0x3F;
+            ch = super.Read();
+            int c3 = ch & 0x3F;
+            ch = super.Read();
+            int c4 = ch & 0x3F;
+            ch = (((((c1 << 6) | c2) << 6) | c3) << 6) | c4;
+        } else if ((ch & 0xE0) == 0xE0) {
+            // 1110xxxx 10xxxxxx 10xxxxxx
+            int c1 = ch & 0x0F;
+            ch = super.Read();
+            int c2 = ch & 0x3F;
+            ch = super.Read();
+            int c3 = ch & 0x3F;
+            ch = (((c1 << 6) | c2) << 6) | c3;
+        } else if ((ch & 0xC0) == 0xC0) {
+            // 110xxxxx 10xxxxxx
+            int c1 = ch & 0x1F;
+            ch = super.Read();
+            int c2 = ch & 0x3F;
+            ch = (c1 << 6) | c2;
+        }
+        return ch;
+    }
+}
+
+// -----------------------------------------------------------------------------------
+// StartStates -- maps characters to start states of tokens
+// -----------------------------------------------------------------------------------
+class StartStates {
+
+    private static class Elem {
+
+        public int key, val;
+        public Elem next;
+
+        public Elem(int key, int val) {
+            this.key = key;
+            this.val = val;
+        }
+    }
+
+    private Elem[] tab = new Elem[128];
+
+    public void set(int key, int val) {
+        Elem e = new Elem(key, val);
+        int k = key % 128;
+        e.next = tab[k];
+        tab[k] = e;
+    }
+
+    public int state(int key) {
+        Elem e = tab[key % 128];
+        while (e != null && e.key != key)
+            e = e.next;
+        return e == null ? 0 : e.val;
+    }
+}
+
+// -----------------------------------------------------------------------------------
+// Scanner
+// -----------------------------------------------------------------------------------
+@SuppressWarnings({"rawtypes", "unchecked"})
+public class Scanner {
+
+    static final char EOL = '\n';
+    static final int eofSym = 0;
+-->declarations
+
+    public Buffer buffer; // scanner buffer
+
+    Token t; // current token
+    int ch; // current input character
+    int pos; // byte position of current character
+    int charPos; // position by unicode characters starting with 0
+    int col; // column number of current character
+    int line; // line number of current character
+    int oldEols; // EOLs that appeared in a comment;
+    static final StartStates start; // maps initial token character to start state
+    static final Map literals; // maps literal strings to literal kinds
+
+    Token tokens; // list of tokens already peeked (first token is a dummy)
+    Token pt; // current peek token
+
+    char[] tval = new char[16]; // token text used in NextToken(), dynamically enlarged
+    int tlen; // length of current token
+
+    static {
+        start = new StartStates();
+        literals = new HashMap();
+-->initialization
+    }
+
+    public Scanner(String fileName) {
+        buffer = new Buffer(fileName);
+        Init();
+    }
+
+    public Scanner(InputStream s) {
+        buffer = new Buffer(s);
+        Init();
+    }
+
+    void Init() {
+        pos = -1;
+        line = 1;
+        col = 0;
+        charPos = -1;
+        oldEols = 0;
+        NextCh();
+        if (ch == 0xEF) { // check optional byte order mark for UTF-8
+            NextCh();
+            int ch1 = ch;
+            NextCh();
+            int ch2 = ch;
+            if (ch1 != 0xBB || ch2 != 0xBF) {
+                throw new FatalError("Illegal byte order mark at start of file");
+            }
+            buffer = new UTF8Buffer(buffer);
+            col = 0;
+            charPos = -1;
+            NextCh();
+        }
+        pt = tokens = new Token(); // first token is a dummy
+    }
+
+    void NextCh() {
+        if (oldEols > 0) {
+            ch = EOL;
+            oldEols--;
+        } else {
+            pos = buffer.getPos();
+            // buffer reads unicode chars, if UTF8 has been detected
+            ch = buffer.Read();
+            col++;
+            charPos++;
+            // replace isolated '\r' by '\n' in order to make
+            // eol handling uniform across Windows, Unix and Mac
+            if (ch == '\r' && buffer.Peek() != '\n')
+                ch = EOL;
+            if (ch == EOL) {
+                line++;
+                col = 0;
+            }
+        }
+-->casing
+    }
+
+    void AddCh() {
+        if (tlen >= tval.length) {
+            char[] newBuf = new char[2 * tval.length];
+            System.arraycopy(tval, 0, newBuf, 0, tval.length);
+            tval = newBuf;
+        }
+        if (ch != Buffer.EOF) {
+-->casing2
+            NextCh();
+        }
+    }
+	
+-->comments
+
+    void CheckLiteral() {
+        String val = t.val;
+-->casing3
+        Object kind = literals.get(val);
+        if (kind != null) {
+            t.kind = ((Integer) kind).intValue();
+        }
+    }
+
+    Token NextToken() {
+        while (ch == ' ' || 
+-->scan1
+		) NextCh();
+-->scan2
+        int recKind = noSym;
+        int recEnd = pos;
+        t = new Token();
+        t.pos = pos;
+        t.col = col;
+        t.line = line;
+        t.charPos = charPos;
+        int state = start.state(ch);
+        tlen = 0;
+        AddCh();
+
+        loop: for (;;) {
+            switch (state) {
+                case -1: {
+                    t.kind = eofSym;
+                    break loop;
+                } // NextCh already done
+                case 0: {
+                    if (recKind != noSym) {
+                        tlen = recEnd - t.pos;
+                        SetScannerBehindT();
+                    }
+                    t.kind = recKind;
+                    break loop;
+                } // NextCh already done
+-->scan3
+            }
+        }
+        t.val = new String(tval, 0, tlen);
+        return t;
+    }
+
+    private void SetScannerBehindT() {
+        buffer.setPos(t.pos);
+        NextCh();
+        line = t.line;
+        col = t.col;
+        charPos = t.charPos;
+        for (int i = 0; i < tlen; i++)
+            NextCh();
+    }
+
+    // get the next token (possibly a token already seen during peeking)
+    public Token Scan() {
+        if (tokens.next == null) {
+            return NextToken();
+        } else {
+            pt = tokens = tokens.next;
+            return tokens;
+        }
+    }
+
+    // get the next token, ignore pragmas
+    public Token Peek() {
+        do {
+            if (pt.next == null) {
+                pt.next = NextToken();
+            }
+            pt = pt.next;
+        } while (pt.kind > maxT); // skip pragmas
+
+        return pt;
+    }
+
+    // make sure that peeking starts at current scan position
+    public void ResetPeek() {
+        pt = tokens;
+    }
+
+    // The following methods are used for the CLNG Editor and will be called with java.Reflection.
+    // If the editor won't be used these 3 functions are obsolete,
+    // otherwise changes within the signature of the methods will result in Syntax Highlighting not working properly
+// anymore.
+
+    // get the offset of the next Token
+    public int getPeekTokenOffset() {
+        return pt.pos;
+    }
+
+    // get the String value of the Token
+    public String getPeekTokenVal() {
+        return pt.val;
+    }
+
+    // get the Kind value of the Token
+    public int getPeekTokenKind() {
+        return pt.kind;
+    }
+
+} // end Scanner
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Scanner.java	Fri Dec 21 10:45:37 2012 -0800
@@ -0,0 +1,636 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ // The content of this file is automatically generated. DO NOT EDIT.
+
+package com.oracle.truffle.sl.parser;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.Map;
+import java.util.HashMap;
+
+// Checkstyle: stop
+class Token {
+
+    public int kind; // token kind
+    public int pos; // token position in bytes in the source text (starting at 0)
+    public int charPos; // token position in characters in the source text (starting at 0)
+    public int col; // token column (starting at 1)
+    public int line; // token line (starting at 1)
+    public String val; // token value
+    public Token next; // ML 2005-03-11 Peek tokens are kept in linked list
+}
+
+// -----------------------------------------------------------------------------------
+// Buffer
+// -----------------------------------------------------------------------------------
+class Buffer {
+
+    // This Buffer supports the following cases:
+    // 1) seekable stream (file)
+    // a) whole stream in buffer
+    // b) part of stream in buffer
+    // 2) non seekable stream (network, console)
+
+    public static final int EOF = Character.MAX_VALUE + 1;
+    private static final int MIN_BUFFER_LENGTH = 1024; // 1KB
+    private static final int MAX_BUFFER_LENGTH = MIN_BUFFER_LENGTH * 64; // 64KB
+    private byte[] buf; // input buffer
+    private int bufStart; // position of first byte in buffer relative to input stream
+    private int bufLen; // length of buffer
+    private int fileLen; // length of input stream (may change if stream is no file)
+    private int bufPos; // current position in buffer
+    private RandomAccessFile file; // input stream (seekable)
+    private InputStream stream; // growing input stream (e.g.: console, network)
+
+    public Buffer(InputStream s) {
+        stream = s;
+        fileLen = bufLen = bufStart = bufPos = 0;
+        buf = new byte[MIN_BUFFER_LENGTH];
+    }
+
+    public Buffer(String fileName) {
+        try {
+            file = new RandomAccessFile(fileName, "r");
+            fileLen = (int) file.length();
+            bufLen = Math.min(fileLen, MAX_BUFFER_LENGTH);
+            buf = new byte[bufLen];
+            bufStart = Integer.MAX_VALUE; // nothing in buffer so far
+            if (fileLen > 0)
+                setPos(0); // setup buffer to position 0 (start)
+            else
+                bufPos = 0; // index 0 is already after the file, thus setPos(0) is invalid
+            if (bufLen == fileLen)
+                Close();
+        } catch (IOException e) {
+            throw new FatalError("Could not open file " + fileName);
+        }
+    }
+
+    // don't use b after this call anymore
+    // called in UTF8Buffer constructor
+    protected Buffer(Buffer b) {
+        buf = b.buf;
+        bufStart = b.bufStart;
+        bufLen = b.bufLen;
+        fileLen = b.fileLen;
+        bufPos = b.bufPos;
+        file = b.file;
+        stream = b.stream;
+        // keep finalize from closing the file
+        b.file = null;
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        super.finalize();
+        Close();
+    }
+
+    protected void Close() {
+        if (file != null) {
+            try {
+                file.close();
+                file = null;
+            } catch (IOException e) {
+                throw new FatalError(e.getMessage());
+            }
+        }
+    }
+
+    public int Read() {
+        if (bufPos < bufLen) {
+            return buf[bufPos++] & 0xff; // mask out sign bits
+        } else if (getPos() < fileLen) {
+            setPos(getPos()); // shift buffer start to pos
+            return buf[bufPos++] & 0xff; // mask out sign bits
+        } else if (stream != null && ReadNextStreamChunk() > 0) {
+            return buf[bufPos++] & 0xff; // mask out sign bits
+        } else {
+            return EOF;
+        }
+    }
+
+    public int Peek() {
+        int curPos = getPos();
+        int ch = Read();
+        setPos(curPos);
+        return ch;
+    }
+
+    // beg .. begin, zero-based, inclusive, in byte
+    // end .. end, zero-based, exclusive, in byte
+    public String GetString(int beg, int end) {
+        int len = 0;
+        char[] buffer = new char[end - beg];
+        int oldPos = getPos();
+        setPos(beg);
+        while (getPos() < end)
+            buffer[len++] = (char) Read();
+        setPos(oldPos);
+        return new String(buffer, 0, len);
+    }
+
+    public int getPos() {
+        return bufPos + bufStart;
+    }
+
+    public void setPos(int value) {
+        if (value >= fileLen && stream != null) {
+            // Wanted position is after buffer and the stream
+            // is not seek-able e.g. network or console,
+            // thus we have to read the stream manually till
+            // the wanted position is in sight.
+            while (value >= fileLen && ReadNextStreamChunk() > 0) {
+                // nothing to do...
+            }
+        }
+
+        if (value < 0 || value > fileLen) {
+            throw new FatalError("buffer out of bounds access, position: " + value);
+        }
+
+        if (value >= bufStart && value < bufStart + bufLen) { // already in buffer
+            bufPos = value - bufStart;
+        } else if (file != null) { // must be swapped in
+            try {
+                file.seek(value);
+                bufLen = file.read(buf);
+                bufStart = value;
+                bufPos = 0;
+            } catch (IOException e) {
+                throw new FatalError(e.getMessage());
+            }
+        } else {
+            // set the position to the end of the file, Pos will return fileLen.
+            bufPos = fileLen - bufStart;
+        }
+    }
+
+    // Read the next chunk of bytes from the stream, increases the buffer
+    // if needed and updates the fields fileLen and bufLen.
+    // Returns the number of bytes read.
+    private int ReadNextStreamChunk() {
+        int free = buf.length - bufLen;
+        if (free == 0) {
+            // in the case of a growing input stream
+            // we can neither seek in the stream, nor can we
+            // foresee the maximum length, thus we must adapt
+            // the buffer size on demand.
+            byte[] newBuf = new byte[bufLen * 2];
+            System.arraycopy(buf, 0, newBuf, 0, bufLen);
+            buf = newBuf;
+            free = bufLen;
+        }
+
+        int read;
+        try {
+            read = stream.read(buf, bufLen, free);
+        } catch (IOException ioex) {
+            throw new FatalError(ioex.getMessage());
+        }
+
+        if (read > 0) {
+            fileLen = bufLen = (bufLen + read);
+            return read;
+        }
+        // end of stream reached
+        return 0;
+    }
+}
+
+// -----------------------------------------------------------------------------------
+// UTF8Buffer
+// -----------------------------------------------------------------------------------
+class UTF8Buffer extends Buffer {
+
+    UTF8Buffer(Buffer b) {
+        super(b);
+    }
+
+    @Override
+    public int Read() {
+        int ch;
+        do {
+            ch = super.Read();
+            // until we find a utf8 start (0xxxxxxx or 11xxxxxx)
+        } while ((ch >= 128) && ((ch & 0xC0) != 0xC0) && (ch != EOF));
+        if (ch < 128 || ch == EOF) {
+            // nothing to do, first 127 chars are the same in ascii and utf8
+            // 0xxxxxxx or end of file character
+        } else if ((ch & 0xF0) == 0xF0) {
+            // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+            int c1 = ch & 0x07;
+            ch = super.Read();
+            int c2 = ch & 0x3F;
+            ch = super.Read();
+            int c3 = ch & 0x3F;
+            ch = super.Read();
+            int c4 = ch & 0x3F;
+            ch = (((((c1 << 6) | c2) << 6) | c3) << 6) | c4;
+        } else if ((ch & 0xE0) == 0xE0) {
+            // 1110xxxx 10xxxxxx 10xxxxxx
+            int c1 = ch & 0x0F;
+            ch = super.Read();
+            int c2 = ch & 0x3F;
+            ch = super.Read();
+            int c3 = ch & 0x3F;
+            ch = (((c1 << 6) | c2) << 6) | c3;
+        } else if ((ch & 0xC0) == 0xC0) {
+            // 110xxxxx 10xxxxxx
+            int c1 = ch & 0x1F;
+            ch = super.Read();
+            int c2 = ch & 0x3F;
+            ch = (c1 << 6) | c2;
+        }
+        return ch;
+    }
+}
+
+// -----------------------------------------------------------------------------------
+// StartStates -- maps characters to start states of tokens
+// -----------------------------------------------------------------------------------
+class StartStates {
+
+    private static class Elem {
+
+        public int key, val;
+        public Elem next;
+
+        public Elem(int key, int val) {
+            this.key = key;
+            this.val = val;
+        }
+    }
+
+    private Elem[] tab = new Elem[128];
+
+    public void set(int key, int val) {
+        Elem e = new Elem(key, val);
+        int k = key % 128;
+        e.next = tab[k];
+        tab[k] = e;
+    }
+
+    public int state(int key) {
+        Elem e = tab[key % 128];
+        while (e != null && e.key != key)
+            e = e.next;
+        return e == null ? 0 : e.val;
+    }
+}
+
+// -----------------------------------------------------------------------------------
+// Scanner
+// -----------------------------------------------------------------------------------
+@SuppressWarnings({"rawtypes", "unchecked"})
+public class Scanner {
+
+    static final char EOL = '\n';
+    static final int eofSym = 0;
+	static final int maxT = 25;
+	static final int noSym = 25;
+
+
+    public Buffer buffer; // scanner buffer
+
+    Token t; // current token
+    int ch; // current input character
+    int pos; // byte position of current character
+    int charPos; // position by unicode characters starting with 0
+    int col; // column number of current character
+    int line; // line number of current character
+    int oldEols; // EOLs that appeared in a comment;
+    static final StartStates start; // maps initial token character to start state
+    static final Map literals; // maps literal strings to literal kinds
+
+    Token tokens; // list of tokens already peeked (first token is a dummy)
+    Token pt; // current peek token
+
+    char[] tval = new char[16]; // token text used in NextToken(), dynamically enlarged
+    int tlen; // length of current token
+
+    static {
+        start = new StartStates();
+        literals = new HashMap();
+		for (int i = 65; i <= 90; ++i) start.set(i, 1);
+		for (int i = 97; i <= 122; ++i) start.set(i, 1);
+		for (int i = 49; i <= 57; ++i) start.set(i, 4);
+		start.set(34, 2); 
+		start.set(48, 5); 
+		start.set(123, 6); 
+		start.set(125, 7); 
+		start.set(40, 8); 
+		start.set(41, 9); 
+		start.set(61, 20); 
+		start.set(59, 10); 
+		start.set(60, 21); 
+		start.set(62, 22); 
+		start.set(33, 14); 
+		start.set(43, 16); 
+		start.set(45, 17); 
+		start.set(42, 18); 
+		start.set(47, 19); 
+		start.set(Buffer.EOF, -1);
+		literals.put("function", new Integer(4));
+		literals.put("while", new Integer(7));
+		literals.put("print", new Integer(12));
+		literals.put("return", new Integer(13));
+		literals.put("time", new Integer(24));
+
+    }
+
+    public Scanner(String fileName) {
+        buffer = new Buffer(fileName);
+        Init();
+    }
+
+    public Scanner(InputStream s) {
+        buffer = new Buffer(s);
+        Init();
+    }
+
+    void Init() {
+        pos = -1;
+        line = 1;
+        col = 0;
+        charPos = -1;
+        oldEols = 0;
+        NextCh();
+        if (ch == 0xEF) { // check optional byte order mark for UTF-8
+            NextCh();
+            int ch1 = ch;
+            NextCh();
+            int ch2 = ch;
+            if (ch1 != 0xBB || ch2 != 0xBF) {
+                throw new FatalError("Illegal byte order mark at start of file");
+            }
+            buffer = new UTF8Buffer(buffer);
+            col = 0;
+            charPos = -1;
+            NextCh();
+        }
+        pt = tokens = new Token(); // first token is a dummy
+    }
+
+    void NextCh() {
+        if (oldEols > 0) {
+            ch = EOL;
+            oldEols--;
+        } else {
+            pos = buffer.getPos();
+            // buffer reads unicode chars, if UTF8 has been detected
+            ch = buffer.Read();
+            col++;
+            charPos++;
+            // replace isolated '\r' by '\n' in order to make
+            // eol handling uniform across Windows, Unix and Mac
+            if (ch == '\r' && buffer.Peek() != '\n')
+                ch = EOL;
+            if (ch == EOL) {
+                line++;
+                col = 0;
+            }
+        }
+
+    }
+
+    void AddCh() {
+        if (tlen >= tval.length) {
+            char[] newBuf = new char[2 * tval.length];
+            System.arraycopy(tval, 0, newBuf, 0, tval.length);
+            tval = newBuf;
+        }
+        if (ch != Buffer.EOF) {
+			tval[tlen++] = (char)ch; 
+
+            NextCh();
+        }
+    }
+	
+
+	boolean Comment0() {
+		int level = 1, pos0 = pos, line0 = line, col0 = col, charPos0 = charPos;
+		NextCh();
+		if (ch == '/') {
+			NextCh();
+			for(;;) {
+				if (ch == 10) {
+					level--;
+					if (level == 0) { oldEols = line - line0; NextCh(); return true; }
+					NextCh();
+				} else if (ch == Buffer.EOF) return false;
+				else NextCh();
+			}
+		} else {
+			buffer.setPos(pos0); NextCh(); line = line0; col = col0; charPos = charPos0;
+		}
+		return false;
+	}
+
+	boolean Comment1() {
+		int level = 1, pos0 = pos, line0 = line, col0 = col, charPos0 = charPos;
+		NextCh();
+		if (ch == '*') {
+			NextCh();
+			for(;;) {
+				if (ch == '*') {
+					NextCh();
+					if (ch == '/') {
+						level--;
+						if (level == 0) { oldEols = line - line0; NextCh(); return true; }
+						NextCh();
+					}
+				} else if (ch == Buffer.EOF) return false;
+				else NextCh();
+			}
+		} else {
+			buffer.setPos(pos0); NextCh(); line = line0; col = col0; charPos = charPos0;
+		}
+		return false;
+	}
+
+
+    void CheckLiteral() {
+        String val = t.val;
+
+        Object kind = literals.get(val);
+        if (kind != null) {
+            t.kind = ((Integer) kind).intValue();
+        }
+    }
+
+    Token NextToken() {
+        while (ch == ' ' || 
+			ch >= 9 && ch <= 10 || ch == 13
+		) NextCh();
+		if (ch == '/' && Comment0() ||ch == '/' && Comment1()) return NextToken();
+        int recKind = noSym;
+        int recEnd = pos;
+        t = new Token();
+        t.pos = pos;
+        t.col = col;
+        t.line = line;
+        t.charPos = charPos;
+        int state = start.state(ch);
+        tlen = 0;
+        AddCh();
+
+        loop: for (;;) {
+            switch (state) {
+                case -1: {
+                    t.kind = eofSym;
+                    break loop;
+                } // NextCh already done
+                case 0: {
+                    if (recKind != noSym) {
+                        tlen = recEnd - t.pos;
+                        SetScannerBehindT();
+                    }
+                    t.kind = recKind;
+                    break loop;
+                } // NextCh already done
+				case 1:
+					recEnd = pos; recKind = 1;
+					if (ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z') {AddCh(); state = 1; break;}
+					else {t.kind = 1; t.val = new String(tval, 0, tlen); CheckLiteral(); return t;}
+				case 2:
+					if (ch <= 9 || ch >= 11 && ch <= 12 || ch >= 14 && ch <= '!' || ch >= '#' && ch <= '[' || ch >= ']' && ch <= 65535) {AddCh(); state = 2; break;}
+					else if (ch == '"') {AddCh(); state = 3; break;}
+					else {state = 0; break;}
+				case 3:
+					{t.kind = 2; break loop;}
+				case 4:
+					recEnd = pos; recKind = 3;
+					if (ch >= '0' && ch <= '9') {AddCh(); state = 4; break;}
+					else {t.kind = 3; break loop;}
+				case 5:
+					{t.kind = 3; break loop;}
+				case 6:
+					{t.kind = 5; break loop;}
+				case 7:
+					{t.kind = 6; break loop;}
+				case 8:
+					{t.kind = 8; break loop;}
+				case 9:
+					{t.kind = 9; break loop;}
+				case 10:
+					{t.kind = 11; break loop;}
+				case 11:
+					{t.kind = 16; break loop;}
+				case 12:
+					{t.kind = 17; break loop;}
+				case 13:
+					{t.kind = 18; break loop;}
+				case 14:
+					if (ch == '=') {AddCh(); state = 15; break;}
+					else {state = 0; break;}
+				case 15:
+					{t.kind = 19; break loop;}
+				case 16:
+					{t.kind = 20; break loop;}
+				case 17:
+					{t.kind = 21; break loop;}
+				case 18:
+					{t.kind = 22; break loop;}
+				case 19:
+					{t.kind = 23; break loop;}
+				case 20:
+					recEnd = pos; recKind = 10;
+					if (ch == '=') {AddCh(); state = 13; break;}
+					else {t.kind = 10; break loop;}
+				case 21:
+					recEnd = pos; recKind = 14;
+					if (ch == '=') {AddCh(); state = 11; break;}
+					else {t.kind = 14; break loop;}
+				case 22:
+					recEnd = pos; recKind = 15;
+					if (ch == '=') {AddCh(); state = 12; break;}
+					else {t.kind = 15; break loop;}
+
+            }
+        }
+        t.val = new String(tval, 0, tlen);
+        return t;
+    }
+
+    private void SetScannerBehindT() {
+        buffer.setPos(t.pos);
+        NextCh();
+        line = t.line;
+        col = t.col;
+        charPos = t.charPos;
+        for (int i = 0; i < tlen; i++)
+            NextCh();
+    }
+
+    // get the next token (possibly a token already seen during peeking)
+    public Token Scan() {
+        if (tokens.next == null) {
+            return NextToken();
+        } else {
+            pt = tokens = tokens.next;
+            return tokens;
+        }
+    }
+
+    // get the next token, ignore pragmas
+    public Token Peek() {
+        do {
+            if (pt.next == null) {
+                pt.next = NextToken();
+            }
+            pt = pt.next;
+        } while (pt.kind > maxT); // skip pragmas
+
+        return pt;
+    }
+
+    // make sure that peeking starts at current scan position
+    public void ResetPeek() {
+        pt = tokens;
+    }
+
+    // The following methods are used for the CLNG Editor and will be called with java.Reflection.
+    // If the editor won't be used these 3 functions are obsolete,
+    // otherwise changes within the signature of the methods will result in Syntax Highlighting not working properly
+// anymore.
+
+    // get the offset of the next Token
+    public int getPeekTokenOffset() {
+        return pt.pos;
+    }
+
+    // get the String value of the Token
+    public String getPeekTokenVal() {
+        return pt.val;
+    }
+
+    // get the Kind value of the Token
+    public int getPeekTokenKind() {
+        return pt.kind;
+    }
+
+} // end Scanner
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/SimpleLanguage.atg	Fri Dec 21 10:45:37 2012 -0800
@@ -0,0 +1,158 @@
+COMPILER SimpleLanguage
+
+CHARACTERS
+
+letter = 'A'..'Z' + 'a'..'z'.
+nonZeroDigit = "123456789".
+digit = "0123456789".
+cr = '\r'.
+lf = '\n'.
+tab = '\t'.
+stringChar = ANY - "\"" - '\\' - cr - lf.
+
+TOKENS
+
+identifier = letter {letter | digit}.
+stringLiteral = "\"" { stringChar } "\"".
+numericLiteral = "0" | nonZeroDigit { digit }.
+
+PRAGMAS
+
+COMMENTS FROM "/*" TO "*/"
+COMMENTS FROM "//" TO lf
+IGNORE cr + lf + tab
+
+PRODUCTIONS
+
+SimpleLanguage
+=
+Function 
+{
+	 Function
+}
+.
+
+Function
+=
+"function"                                      (. factory.startFunction(); .)
+identifier                                      (. String name = t.val; .)
+Block<out StatementNode body>                   (. factory.createFunction(body, name); .)
+.
+
+Block<out StatementNode result>
+=                                               (. List<StatementNode> statements = new ArrayList<>(); .)
+"{" 
+{
+    Statement<out StatementNode statement>      (. statements.add(statement); .)
+}
+"}"                                             (. result = factory.createBlock(statements); .)
+.
+
+Statement<out StatementNode result>
+=                                               (. result = null; .)
+(
+    WhileStatement<out result>
+|
+    AssignmentStatement<out result>
+|
+    OutputStatement<out result>
+|
+    ReturnStatement<out result>
+)
+.
+
+WhileStatement<out StatementNode result>
+=
+"while"
+"("
+Expression<out ConditionNode condition>
+")" 
+Block<out StatementNode body>                   (. result = factory.createWhile(condition, body); .)
+.
+
+AssignmentStatement<out StatementNode result>
+=
+identifier                                      (. String name = t.val; .)
+"="
+Expression<out TypedNode rvalue>
+";"                                             (. result = factory.createAssignment(name, rvalue); .)
+.
+
+OutputStatement<out StatementNode result>
+=                                               (. List<TypedNode> expressions = new ArrayList<>(); .)
+"print"
+{
+    Expression<out TypedNode value>             (. expressions.add(value); .)
+}
+";"                                             (. result = factory.createPrint(expressions); .)
+.
+							
+ReturnStatement<out StatementNode result>
+=
+"return"
+Expression<out TypedNode value> ";"             (. result = factory.createReturn(value); .)
+.
+
+Expression<out TypedNode result>
+=
+ValueExpression<out result>
+[
+    ("<" | ">" | "<=" | ">=" | "==" | "!=" )    (.	String op = t.val; .)
+    ValueExpression<out TypedNode right>        (.	result = factory.createBinary(op, result, right); .)
+]
+.
+
+ValueExpression<out TypedNode result>
+=
+Term<out result>
+{
+    ("+" | "-")                                 (. String op = t.val; .)
+    Term<out TypedNode right>                   (. result = factory.createBinary(op, result, right); .)
+}
+.
+
+Term<out TypedNode result>
+=
+Factor<out result>
+{
+    ("*" | "/")                                 (. String op = t.val; .)
+    Factor<out TypedNode right>                 (. result = factory.createBinary(op, result, right); .)
+}
+.
+
+Factor<out TypedNode result>
+=                                               (. result = null; .)
+(
+    TimeRef<out result>
+|
+    VariableRef<out result>
+|
+    StringLiteral<out result>
+|
+    NumericLiteral<out result>
+|
+    "(" Expression<out result> ")"
+)
+.
+
+TimeRef<out TypedNode result>
+=
+"time"                                          (. result = factory.createTime(); .)
+.
+
+VariableRef<out TypedNode result>
+=
+identifier                                      (. result = factory.createLocal(t.val); .)
+.
+
+StringLiteral<out TypedNode result>
+=
+stringLiteral                                   (. result = factory.createStringLiteral(t.val.substring(1, t.val.length() - 1)); .)
+.
+
+NumericLiteral<out TypedNode result>
+=
+numericLiteral                                  (. result = factory.createNumericLiteral(t.val); .)
+.
+
+END SimpleLanguage.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/tools/GraphPrinter.java	Fri Dec 21 10:45:37 2012 -0800
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.sl.tools;
+
+import com.oracle.truffle.api.nodes.*;
+
+public class GraphPrinter {
+
+    public static void print(Node root) {
+        print(root, 0);
+    }
+
+    private static void print(Node node, int level) {
+        for (int i = 0; i < level; i++) {
+            System.out.print("    ");
+        }
+        System.out.println(node == null ? "empty" : node.getClass().getSimpleName());
+        if (node != null) {
+            for (Node child : node.getChildren()) {
+                print(child, level + 1);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/types/FrameSlotNode.java	Fri Dec 21 10:45:37 2012 -0800
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.sl.types;
+
+import com.oracle.truffle.api.frame.*;
+
+public abstract class FrameSlotNode extends TypedNode implements FrameSlotTypeListener {
+
+    protected final FrameSlot slot;
+
+    public FrameSlotNode(FrameSlot slot) {
+        this.slot = slot;
+        slot.registerOneShotTypeListener(this);
+    }
+
+    @Override
+    public void typeChanged(FrameSlot changedSlot, Class< ? > oldType) {
+        if (getParent() != null) {
+            specialize(changedSlot.getType());
+        }
+    }
+
+    protected abstract void specialize(Class< ? > clazz);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/types/TypedNode.java	Fri Dec 21 10:45:37 2012 -0800
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.sl.types;
+
+import java.math.*;
+
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.sl.nodes.*;
+
+public abstract class TypedNode extends ConditionNode {
+
+    @Override
+    public final boolean executeCondition(VirtualFrame frame) {
+        try {
+            return executeBoolean(frame);
+        } catch (UnexpectedResultException ex) {
+            throw new RuntimeException("Illegal type for condition: " + ex.getResult().getClass().getSimpleName());
+        }
+    }
+
+    public abstract boolean executeBoolean(VirtualFrame frame) throws UnexpectedResultException;
+
+    public abstract int executeInteger(VirtualFrame frame) throws UnexpectedResultException;
+
+    public abstract BigInteger executeBigInteger(VirtualFrame frame) throws UnexpectedResultException;
+
+    public abstract String executeString(VirtualFrame frame) throws UnexpectedResultException;
+
+    public abstract Object executeGeneric(VirtualFrame frame);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/types/Types.java	Fri Dec 21 10:45:37 2012 -0800
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.sl.types;
+
+import java.math.*;
+
+import com.oracle.truffle.api.codegen.*;
+
+@TypeSystem(types = {int.class, BigInteger.class, boolean.class, String.class}, nodeBaseClass = TypedNode.class, hasVoid = true)
+public class Types {
+
+    @TypeCheck
+    public boolean isInteger(Object value) {
+        return value instanceof Integer || (value instanceof BigInteger && ((BigInteger) value).bitLength() < Integer.SIZE);
+    }
+
+    @TypeCast
+    public int asInteger(Object value) {
+        assert isInteger(value);
+        if (value instanceof Integer) {
+            return (int) value;
+        } else {
+            int result = ((BigInteger) value).intValue();
+            assert BigInteger.valueOf(result).equals(value) : "Loosing precision";
+            return result;
+        }
+    }
+
+    @GuardCheck
+    public boolean isString(Object a, Object b) {
+        return a instanceof String || b instanceof String;
+    }
+
+    @TypeCheck
+    public boolean isBigInteger(Object value) {
+        return value instanceof Integer || value instanceof BigInteger;
+    }
+
+    @TypeCast
+    public BigInteger asBigInteger(Object value) {
+        if (value instanceof Integer) {
+            return BigInteger.valueOf((int) value);
+        } else {
+            return (BigInteger) value;
+        }
+    }
+
+    @TypeCast
+    public BigInteger asBigInteger(int value) {
+        return BigInteger.valueOf(value);
+    }
+
+    @TypeCheck
+    public boolean isBigInteger(@SuppressWarnings("unused") int value) {
+        return true;
+    }
+
+}
--- a/mx/projects	Fri Dec 21 10:44:31 2012 -0800
+++ b/mx/projects	Fri Dec 21 10:45:37 2012 -0800
@@ -286,3 +286,18 @@
 project@com.oracle.truffle.codegen.processor@checkstyle=com.oracle.graal.graph
 project@com.oracle.truffle.codegen.processor@javaCompliance=1.7
 
+# truffle.sl
+project@com.oracle.truffle.sl@subDir=graal
+project@com.oracle.truffle.sl@sourceDirs=src
+project@com.oracle.truffle.sl@dependencies=com.oracle.truffle.api.codegen
+project@com.oracle.truffle.sl@checkstyle=com.oracle.graal.graph
+project@com.oracle.truffle.sl@javaCompliance=1.7
+project@com.oracle.truffle.sl@annotationProcessors=com.oracle.truffle.codegen.processor
+
+# truffle.sl.test
+project@com.oracle.truffle.sl.test@subDir=graal
+project@com.oracle.truffle.sl.test@sourceDirs=src
+project@com.oracle.truffle.sl.test@dependencies=com.oracle.truffle.sl,JUNIT
+project@com.oracle.truffle.sl.test@checkstyle=com.oracle.graal.graph
+project@com.oracle.truffle.sl.test@javaCompliance=1.7
+