├── part-01 ├── build.gradle └── src │ ├── main │ └── java │ │ └── com │ │ └── endoflineblog │ │ └── truffle │ │ └── part_01 │ │ ├── IntLiteralNode.java │ │ └── AdditionNode.java │ └── test │ └── java │ └── com │ └── endoflineblog │ └── truffle │ └── part_01 │ ├── ExecuteNodesTest.java │ └── OverflowTest.java ├── part-02 ├── build.gradle └── src │ └── main │ └── java │ └── com │ └── endoflineblog │ └── truffle │ └── part_02 │ ├── IntLiteralNode.java │ └── EasyScriptRootNode.java ├── part-03 ├── build.gradle └── src │ └── main │ └── java │ └── com │ └── endoflineblog │ └── truffle │ └── part_03 │ ├── IntLiteralNode.java │ ├── EasyScriptRootNode.java │ └── DoubleLiteralNode.java ├── .gitignore ├── part-09 ├── img │ └── igv-screenshot.png ├── src │ └── main │ │ └── java │ │ └── com │ │ └── endoflineblog │ │ └── truffle │ │ └── part_09 │ │ ├── exceptions │ │ ├── BreakException.java │ │ ├── ContinueException.java │ │ ├── ReturnException.java │ │ └── EasyScriptException.java │ │ ├── EasyScriptTypeSystem.java │ │ ├── nodes │ │ ├── exprs │ │ │ ├── BinaryOperationExprNode.java │ │ │ ├── functions │ │ │ │ ├── built_in │ │ │ │ │ └── BuiltInFunctionBodyExprNode.java │ │ │ │ └── ReadFunctionArgExprNode.java │ │ │ └── comparisons │ │ │ │ ├── LesserExprNode.java │ │ │ │ ├── GreaterExprNode.java │ │ │ │ ├── LesserOrEqualExprNode.java │ │ │ │ └── GreaterOrEqualExprNode.java │ │ ├── stmts │ │ │ ├── controlflow │ │ │ │ ├── BreakStmtNode.java │ │ │ │ ├── ContinueStmtNode.java │ │ │ │ └── ReturnStmtNode.java │ │ │ └── EasyScriptStmtNode.java │ │ └── EasyScriptNode.java │ │ ├── common │ │ └── DeclarationKind.java │ │ ├── runtime │ │ └── Undefined.java │ │ ├── parsing │ │ └── ParsingResult.java │ │ └── EasyScriptLanguageContext.java └── build.gradle ├── part-16 ├── img │ ├── chrome-devtools.png │ └── debugger-variables.png ├── src │ ├── test │ │ ├── resources │ │ │ ├── exceptions-stack-top-level.js │ │ │ ├── exceptions-throw-f3.js │ │ │ └── exceptions-stack-from-func.js │ │ └── java │ │ │ └── com │ │ │ └── endoflineblog │ │ │ └── truffle │ │ │ └── part_16 │ │ │ └── ParsingTest.java │ └── main │ │ ├── java │ │ └── com │ │ │ └── endoflineblog │ │ │ └── truffle │ │ │ └── part_16 │ │ │ ├── exceptions │ │ │ ├── BreakException.java │ │ │ ├── ContinueException.java │ │ │ └── ReturnException.java │ │ │ ├── EasyScriptTypeSystem.java │ │ │ ├── nodes │ │ │ ├── exprs │ │ │ │ ├── BinaryOperationExprNode.java │ │ │ │ ├── objects │ │ │ │ │ └── ThisExprNode.java │ │ │ │ └── functions │ │ │ │ │ └── built_in │ │ │ │ │ └── BuiltInFunctionBodyExprNode.java │ │ │ ├── EasyScriptNode.java │ │ │ └── stmts │ │ │ │ └── controlflow │ │ │ │ ├── BreakStmtNode.java │ │ │ │ └── ContinueStmtNode.java │ │ │ ├── common │ │ │ └── DeclarationKind.java │ │ │ └── runtime │ │ │ └── Undefined.java │ │ └── resources │ │ └── fibonacci.js └── build.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── part-15 ├── src │ ├── test │ │ ├── resources │ │ │ ├── exceptions-stack-top-level.js │ │ │ ├── exceptions-throw-f3.js │ │ │ └── exceptions-stack-from-func.js │ │ └── java │ │ │ └── com │ │ │ └── endoflineblog │ │ │ └── truffle │ │ │ └── part_15 │ │ │ └── ParsingTest.java │ └── main │ │ └── java │ │ └── com │ │ └── endoflineblog │ │ └── truffle │ │ └── part_15 │ │ ├── exceptions │ │ ├── BreakException.java │ │ ├── ContinueException.java │ │ └── ReturnException.java │ │ ├── EasyScriptTypeSystem.java │ │ ├── nodes │ │ ├── exprs │ │ │ ├── BinaryOperationExprNode.java │ │ │ ├── objects │ │ │ │ └── ThisExprNode.java │ │ │ └── functions │ │ │ │ ├── built_in │ │ │ │ └── BuiltInFunctionBodyExprNode.java │ │ │ │ └── ReadFunctionArgExprNode.java │ │ ├── stmts │ │ │ ├── controlflow │ │ │ │ ├── BreakStmtNode.java │ │ │ │ └── ContinueStmtNode.java │ │ │ └── EasyScriptStmtNode.java │ │ └── EasyScriptNode.java │ │ ├── common │ │ └── DeclarationKind.java │ │ ├── runtime │ │ └── Undefined.java │ │ └── parsing │ │ └── ParsingResult.java └── build.gradle ├── part-05 ├── build.gradle └── src │ └── main │ ├── java │ └── com │ │ └── endoflineblog │ │ └── truffle │ │ └── part_05 │ │ ├── EasyScriptTypeSystem.java │ │ ├── nodes │ │ ├── stmts │ │ │ ├── EasyScriptStmtNode.java │ │ │ └── ExprStmtNode.java │ │ ├── EasyScriptNode.java │ │ └── exprs │ │ │ ├── IntLiteralExprNode.java │ │ │ ├── GlobalVarReferenceExprNode.java │ │ │ ├── UndefinedLiteralExprNode.java │ │ │ ├── DoubleLiteralExprNode.java │ │ │ └── GlobalVarAssignmentExprNode.java │ │ ├── DeclarationKind.java │ │ ├── runtime │ │ └── Undefined.java │ │ └── EasyScriptException.java │ └── antlr │ └── com │ └── endoflineblog │ └── truffle │ └── part_05 │ └── EasyScript.g4 ├── part-06 ├── build.gradle └── src │ └── main │ └── java │ └── com │ └── endoflineblog │ └── truffle │ └── part_06 │ ├── nodes │ ├── EasyScriptNode.java │ ├── stmts │ │ ├── EasyScriptStmtNode.java │ │ └── ExprStmtNode.java │ ├── exprs │ │ ├── IntLiteralExprNode.java │ │ ├── GlobalVarReferenceExprNode.java │ │ ├── UndefinedLiteralExprNode.java │ │ ├── DoubleLiteralExprNode.java │ │ └── GlobalVarAssignmentExprNode.java │ └── FunctionRootNode.java │ ├── EasyScriptException.java │ ├── DeclarationKind.java │ ├── EasyScriptTypeSystem.java │ ├── runtime │ └── Undefined.java │ └── EasyScriptLanguageContext.java ├── part-07 ├── build.gradle └── src │ └── main │ └── java │ └── com │ └── endoflineblog │ └── truffle │ └── part_07 │ ├── EasyScriptTypeSystem.java │ ├── EasyScriptException.java │ ├── nodes │ ├── stmts │ │ └── EasyScriptStmtNode.java │ └── exprs │ │ ├── functions │ │ └── built_in │ │ │ └── BuiltInFunctionBodyExprNode.java │ │ ├── IntLiteralExprNode.java │ │ ├── GlobalVarReferenceExprNode.java │ │ ├── UndefinedLiteralExprNode.java │ │ ├── DoubleLiteralExprNode.java │ │ └── GlobalVarAssignmentExprNode.java │ ├── DeclarationKind.java │ ├── runtime │ └── Undefined.java │ └── EasyScriptLanguageContext.java ├── part-08 ├── build.gradle └── src │ └── main │ └── java │ └── com │ └── endoflineblog │ └── truffle │ └── part_08 │ ├── exceptions │ ├── BreakException.java │ ├── ContinueException.java │ ├── ReturnException.java │ └── EasyScriptException.java │ ├── nodes │ ├── exprs │ │ ├── BinaryOperationExprNode.java │ │ ├── functions │ │ │ ├── built_in │ │ │ │ └── BuiltInFunctionBodyExprNode.java │ │ │ └── ReadFunctionArgExprNode.java │ │ └── comparisons │ │ │ ├── LesserExprNode.java │ │ │ ├── GreaterExprNode.java │ │ │ ├── LesserOrEqualExprNode.java │ │ │ └── GreaterOrEqualExprNode.java │ ├── stmts │ │ ├── controlflow │ │ │ ├── BreakStmtNode.java │ │ │ ├── ContinueStmtNode.java │ │ │ └── ReturnStmtNode.java │ │ └── EasyScriptStmtNode.java │ └── EasyScriptNode.java │ ├── EasyScriptTypeSystem.java │ ├── common │ └── DeclarationKind.java │ ├── parsing │ └── ParsingResult.java │ ├── runtime │ └── Undefined.java │ └── EasyScriptLanguageContext.java ├── part-04 ├── build.gradle └── src │ ├── main │ └── antlr │ │ └── com │ │ └── endoflineblog │ │ └── truffle │ │ └── part_04 │ │ └── EasyScript.g4 │ └── test │ └── java │ └── com │ └── endoflineblog │ └── truffle │ └── part_04 │ └── PolyglotTest.java ├── settings.gradle ├── part-10 ├── src │ └── main │ │ └── java │ │ └── com │ │ └── endoflineblog │ │ └── truffle │ │ └── part_10 │ │ ├── exceptions │ │ ├── BreakException.java │ │ ├── ContinueException.java │ │ ├── ReturnException.java │ │ └── EasyScriptException.java │ │ ├── EasyScriptTypeSystem.java │ │ ├── nodes │ │ ├── exprs │ │ │ ├── BinaryOperationExprNode.java │ │ │ ├── functions │ │ │ │ ├── built_in │ │ │ │ │ └── BuiltInFunctionBodyExprNode.java │ │ │ │ └── ReadFunctionArgExprNode.java │ │ │ └── comparisons │ │ │ │ ├── LesserExprNode.java │ │ │ │ ├── GreaterExprNode.java │ │ │ │ ├── LesserOrEqualExprNode.java │ │ │ │ └── GreaterOrEqualExprNode.java │ │ ├── stmts │ │ │ ├── controlflow │ │ │ │ ├── BreakStmtNode.java │ │ │ │ ├── ContinueStmtNode.java │ │ │ │ └── ReturnStmtNode.java │ │ │ └── EasyScriptStmtNode.java │ │ └── EasyScriptNode.java │ │ ├── common │ │ └── DeclarationKind.java │ │ ├── runtime │ │ └── Undefined.java │ │ └── parsing │ │ └── ParsingResult.java └── build.gradle ├── part-11 ├── src │ └── main │ │ └── java │ │ └── com │ │ └── endoflineblog │ │ └── truffle │ │ └── part_11 │ │ ├── exceptions │ │ ├── BreakException.java │ │ ├── ContinueException.java │ │ ├── ReturnException.java │ │ └── EasyScriptException.java │ │ ├── EasyScriptTypeSystem.java │ │ ├── nodes │ │ ├── exprs │ │ │ ├── BinaryOperationExprNode.java │ │ │ ├── functions │ │ │ │ ├── built_in │ │ │ │ │ └── BuiltInFunctionBodyExprNode.java │ │ │ │ └── ReadFunctionArgExprNode.java │ │ │ └── literals │ │ │ │ └── StringLiteralExprNode.java │ │ ├── stmts │ │ │ ├── controlflow │ │ │ │ ├── BreakStmtNode.java │ │ │ │ ├── ContinueStmtNode.java │ │ │ │ └── ReturnStmtNode.java │ │ │ └── EasyScriptStmtNode.java │ │ └── EasyScriptNode.java │ │ ├── common │ │ └── DeclarationKind.java │ │ ├── runtime │ │ ├── Undefined.java │ │ └── StringPrototype.java │ │ └── parsing │ │ └── ParsingResult.java └── build.gradle ├── part-12 ├── src │ ├── main │ │ └── java │ │ │ └── com │ │ │ └── endoflineblog │ │ │ └── truffle │ │ │ └── part_12 │ │ │ ├── exceptions │ │ │ ├── BreakException.java │ │ │ ├── ContinueException.java │ │ │ ├── ReturnException.java │ │ │ └── EasyScriptException.java │ │ │ ├── EasyScriptTypeSystem.java │ │ │ ├── nodes │ │ │ ├── exprs │ │ │ │ ├── BinaryOperationExprNode.java │ │ │ │ ├── functions │ │ │ │ │ ├── built_in │ │ │ │ │ │ └── BuiltInFunctionBodyExprNode.java │ │ │ │ │ └── ReadFunctionArgExprNode.java │ │ │ │ ├── properties │ │ │ │ │ └── PropertyReadExprNode.java │ │ │ │ └── DynamicObjectReferenceExprNode.java │ │ │ ├── stmts │ │ │ │ ├── controlflow │ │ │ │ │ ├── BreakStmtNode.java │ │ │ │ │ ├── ContinueStmtNode.java │ │ │ │ │ └── ReturnStmtNode.java │ │ │ │ └── EasyScriptStmtNode.java │ │ │ └── EasyScriptNode.java │ │ │ ├── runtime │ │ │ ├── StringPrototype.java │ │ │ └── Undefined.java │ │ │ ├── common │ │ │ └── DeclarationKind.java │ │ │ └── parsing │ │ │ └── ParsingResult.java │ └── test │ │ └── java │ │ └── com │ │ └── endoflineblog │ │ └── truffle │ │ └── part_12 │ │ └── ParsingTest.java └── build.gradle ├── part-13 ├── src │ ├── main │ │ └── java │ │ │ └── com │ │ │ └── endoflineblog │ │ │ └── truffle │ │ │ └── part_13 │ │ │ ├── exceptions │ │ │ ├── BreakException.java │ │ │ ├── ContinueException.java │ │ │ ├── ReturnException.java │ │ │ └── EasyScriptException.java │ │ │ ├── EasyScriptTypeSystem.java │ │ │ ├── nodes │ │ │ ├── exprs │ │ │ │ ├── BinaryOperationExprNode.java │ │ │ │ ├── objects │ │ │ │ │ └── ThisExprNode.java │ │ │ │ └── functions │ │ │ │ │ ├── built_in │ │ │ │ │ └── BuiltInFunctionBodyExprNode.java │ │ │ │ │ └── ReadFunctionArgExprNode.java │ │ │ ├── stmts │ │ │ │ ├── controlflow │ │ │ │ │ ├── BreakStmtNode.java │ │ │ │ │ ├── ContinueStmtNode.java │ │ │ │ │ └── ReturnStmtNode.java │ │ │ │ └── EasyScriptStmtNode.java │ │ │ └── EasyScriptNode.java │ │ │ ├── common │ │ │ └── DeclarationKind.java │ │ │ ├── runtime │ │ │ └── Undefined.java │ │ │ └── parsing │ │ │ └── ParsingResult.java │ └── test │ │ └── java │ │ └── com │ │ └── endoflineblog │ │ └── truffle │ │ └── part_13 │ │ └── ParsingTest.java └── build.gradle ├── part-14 ├── src │ ├── main │ │ └── java │ │ │ └── com │ │ │ └── endoflineblog │ │ │ └── truffle │ │ │ └── part_14 │ │ │ ├── exceptions │ │ │ ├── BreakException.java │ │ │ ├── ContinueException.java │ │ │ ├── ReturnException.java │ │ │ └── EasyScriptException.java │ │ │ ├── EasyScriptTypeSystem.java │ │ │ ├── nodes │ │ │ ├── exprs │ │ │ │ ├── BinaryOperationExprNode.java │ │ │ │ ├── objects │ │ │ │ │ └── ThisExprNode.java │ │ │ │ └── functions │ │ │ │ │ ├── built_in │ │ │ │ │ └── BuiltInFunctionBodyExprNode.java │ │ │ │ │ └── ReadFunctionArgExprNode.java │ │ │ ├── stmts │ │ │ │ ├── controlflow │ │ │ │ │ ├── BreakStmtNode.java │ │ │ │ │ ├── ContinueStmtNode.java │ │ │ │ │ └── ReturnStmtNode.java │ │ │ │ └── EasyScriptStmtNode.java │ │ │ └── EasyScriptNode.java │ │ │ ├── common │ │ │ └── DeclarationKind.java │ │ │ ├── runtime │ │ │ └── Undefined.java │ │ │ └── parsing │ │ │ └── ParsingResult.java │ └── test │ │ └── java │ │ └── com │ │ └── endoflineblog │ │ └── truffle │ │ └── part_14 │ │ └── ParsingTest.java └── build.gradle └── .github └── workflows └── build.yaml /part-01/build.gradle: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /part-02/build.gradle: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /part-03/build.gradle: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | *.iml 3 | .gradle/ 4 | build/ 5 | .java-version 6 | -------------------------------------------------------------------------------- /part-09/img/igv-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skinny85/graalvm-truffle-tutorial/HEAD/part-09/img/igv-screenshot.png -------------------------------------------------------------------------------- /part-16/img/chrome-devtools.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skinny85/graalvm-truffle-tutorial/HEAD/part-16/img/chrome-devtools.png -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skinny85/graalvm-truffle-tutorial/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /part-16/img/debugger-variables.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skinny85/graalvm-truffle-tutorial/HEAD/part-16/img/debugger-variables.png -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /part-15/src/test/resources/exceptions-stack-top-level.js: -------------------------------------------------------------------------------- 1 | let stackBefore, stackAfter; 2 | 3 | try { 4 | const error = new Error('msg'); 5 | stackBefore = error.stack; 6 | throw error; 7 | } catch (e) { 8 | stackAfter = e.stack; 9 | } 10 | -------------------------------------------------------------------------------- /part-16/src/test/resources/exceptions-stack-top-level.js: -------------------------------------------------------------------------------- 1 | let stackBefore, stackAfter; 2 | 3 | try { 4 | const error = new Error('msg'); 5 | stackBefore = error.stack; 6 | throw error; 7 | } catch (e) { 8 | stackAfter = e.stack; 9 | } 10 | -------------------------------------------------------------------------------- /part-05/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'antlr' 2 | 3 | dependencies { 4 | antlr "org.antlr:antlr4:$antlr_version" 5 | } 6 | 7 | // required to allow GraalVM to discover our EasyScript language class 8 | test { 9 | jvmArgs '-Dgraalvm.locatorDisabled=true' 10 | } 11 | -------------------------------------------------------------------------------- /part-06/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'antlr' 2 | 3 | dependencies { 4 | antlr "org.antlr:antlr4:$antlr_version" 5 | } 6 | 7 | // required to allow GraalVM to discover our EasyScript language class 8 | test { 9 | jvmArgs '-Dgraalvm.locatorDisabled=true' 10 | } 11 | -------------------------------------------------------------------------------- /part-07/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'antlr' 2 | 3 | dependencies { 4 | antlr "org.antlr:antlr4:$antlr_version" 5 | } 6 | 7 | // required to allow GraalVM to discover our EasyScript language class 8 | test { 9 | jvmArgs '-Dgraalvm.locatorDisabled=true' 10 | } 11 | -------------------------------------------------------------------------------- /part-08/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'antlr' 2 | 3 | dependencies { 4 | antlr "org.antlr:antlr4:$antlr_version" 5 | } 6 | 7 | // required to allow GraalVM to discover our EasyScript language class 8 | test { 9 | jvmArgs '-Dgraalvm.locatorDisabled=true' 10 | } 11 | -------------------------------------------------------------------------------- /part-15/src/test/resources/exceptions-throw-f3.js: -------------------------------------------------------------------------------- 1 | function main() { 2 | f1(); 3 | } 4 | function f1() { 5 | let x = f2(); 6 | return x; 7 | } 8 | function f2() { 9 | return f3(); 10 | } 11 | function f3() { 12 | throw 'Exception in f3()'; 13 | } 14 | main(); 15 | -------------------------------------------------------------------------------- /part-16/src/test/resources/exceptions-throw-f3.js: -------------------------------------------------------------------------------- 1 | function main() { 2 | f1(); 3 | } 4 | function f1() { 5 | let x = f2(); 6 | return x; 7 | } 8 | function f2() { 9 | return f3(); 10 | } 11 | function f3() { 12 | throw 'Exception in f3()'; 13 | } 14 | main(); 15 | -------------------------------------------------------------------------------- /part-15/src/test/resources/exceptions-stack-from-func.js: -------------------------------------------------------------------------------- 1 | let stackBefore, stackAfter; 2 | function f() { 3 | const error = new Error('msg'); 4 | stackBefore = error.stack; 5 | try { 6 | throw error; 7 | } catch (e) { 8 | stackAfter = e.stack; 9 | } 10 | } 11 | f(); 12 | -------------------------------------------------------------------------------- /part-16/src/test/resources/exceptions-stack-from-func.js: -------------------------------------------------------------------------------- 1 | let stackBefore, stackAfter; 2 | function f() { 3 | const error = new Error('msg'); 4 | stackBefore = error.stack; 5 | try { 6 | throw error; 7 | } catch (e) { 8 | stackAfter = e.stack; 9 | } 10 | } 11 | f(); 12 | -------------------------------------------------------------------------------- /part-04/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'antlr' 2 | 3 | dependencies { 4 | implementation project(':part-03') 5 | antlr "org.antlr:antlr4:$antlr_version" 6 | } 7 | 8 | // required to allow GraalVM to discover our EasyScript language class 9 | test { 10 | jvmArgs '-Dgraalvm.locatorDisabled=true' 11 | } 12 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'truffle-tutorial' 2 | 3 | include 'part-01', 4 | 'part-02', 5 | 'part-03', 6 | 'part-04', 7 | 'part-05', 8 | 'part-06', 9 | 'part-07', 10 | 'part-08', 11 | 'part-09', 12 | 'part-10', 13 | 'part-11', 14 | 'part-12', 15 | 'part-13', 16 | 'part-14', 17 | 'part-15', 18 | 'part-16' 19 | -------------------------------------------------------------------------------- /part-08/src/main/java/com/endoflineblog/truffle/part_08/exceptions/BreakException.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_08.exceptions; 2 | 3 | import com.oracle.truffle.api.nodes.ControlFlowException; 4 | 5 | /** 6 | * The exception used to implement the {@code break} statement. 7 | * 8 | * @see com.endoflineblog.truffle.part_08.nodes.stmts.controlflow.BreakStmtNode 9 | */ 10 | public final class BreakException extends ControlFlowException { 11 | } 12 | -------------------------------------------------------------------------------- /part-08/src/main/java/com/endoflineblog/truffle/part_08/exceptions/ContinueException.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_08.exceptions; 2 | 3 | import com.oracle.truffle.api.nodes.ControlFlowException; 4 | 5 | /** 6 | * The exception used to implement the {@code continue} statement. 7 | * 8 | * @see com.endoflineblog.truffle.part_08.nodes.stmts.controlflow.ContinueStmtNode 9 | */ 10 | public final class ContinueException extends ControlFlowException { 11 | } 12 | -------------------------------------------------------------------------------- /part-05/src/main/java/com/endoflineblog/truffle/part_05/EasyScriptTypeSystem.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_05; 2 | 3 | import com.oracle.truffle.api.dsl.ImplicitCast; 4 | import com.oracle.truffle.api.dsl.TypeSystem; 5 | 6 | /** 7 | * The TypeSystem for EasyScript, 8 | * the same as in part 3. 9 | */ 10 | @TypeSystem 11 | public abstract class EasyScriptTypeSystem { 12 | @ImplicitCast 13 | public static double castIntToDouble(int value) { 14 | return value; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /part-04/src/main/antlr/com/endoflineblog/truffle/part_04/EasyScript.g4: -------------------------------------------------------------------------------- 1 | grammar EasyScript ; 2 | 3 | @header{ 4 | package com.endoflineblog.truffle.part_04; 5 | } 6 | 7 | start : expr EOF ; 8 | 9 | expr : left=expr '+' right=expr #AddExpr 10 | | literal #LiteralExpr 11 | ; 12 | 13 | literal : INT | DOUBLE ; 14 | 15 | fragment DIGIT : [0-9] ; 16 | INT : DIGIT+ ; 17 | DOUBLE : DIGIT+ '.' DIGIT+ ; 18 | 19 | // skip all whitespace 20 | WS : (' ' | '\r' | '\t' | '\n' | '\f')+ -> skip ; 21 | -------------------------------------------------------------------------------- /part-09/src/main/java/com/endoflineblog/truffle/part_09/exceptions/BreakException.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_09.exceptions; 2 | 3 | import com.oracle.truffle.api.nodes.ControlFlowException; 4 | 5 | /** 6 | * The exception used to implement the {@code break} statement. 7 | * Identical to the class with the same name from part 8. 8 | * 9 | * @see com.endoflineblog.truffle.part_09.nodes.stmts.controlflow.BreakStmtNode 10 | */ 11 | public final class BreakException extends ControlFlowException { 12 | } 13 | -------------------------------------------------------------------------------- /part-10/src/main/java/com/endoflineblog/truffle/part_10/exceptions/BreakException.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_10.exceptions; 2 | 3 | import com.oracle.truffle.api.nodes.ControlFlowException; 4 | 5 | /** 6 | * The exception used to implement the {@code break} statement. 7 | * Identical to the class with the same name from part 9. 8 | * 9 | * @see com.endoflineblog.truffle.part_10.nodes.stmts.controlflow.BreakStmtNode 10 | */ 11 | public final class BreakException extends ControlFlowException { 12 | } 13 | -------------------------------------------------------------------------------- /part-11/src/main/java/com/endoflineblog/truffle/part_11/exceptions/BreakException.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_11.exceptions; 2 | 3 | import com.oracle.truffle.api.nodes.ControlFlowException; 4 | 5 | /** 6 | * The exception used to implement the {@code break} statement. 7 | * Identical to the class with the same name from part 10. 8 | * 9 | * @see com.endoflineblog.truffle.part_11.nodes.stmts.controlflow.BreakStmtNode 10 | */ 11 | public final class BreakException extends ControlFlowException { 12 | } 13 | -------------------------------------------------------------------------------- /part-12/src/main/java/com/endoflineblog/truffle/part_12/exceptions/BreakException.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_12.exceptions; 2 | 3 | import com.oracle.truffle.api.nodes.ControlFlowException; 4 | 5 | /** 6 | * The exception used to implement the {@code break} statement. 7 | * Identical to the class with the same name from part 11. 8 | * 9 | * @see com.endoflineblog.truffle.part_12.nodes.stmts.controlflow.BreakStmtNode 10 | */ 11 | public final class BreakException extends ControlFlowException { 12 | } 13 | -------------------------------------------------------------------------------- /part-13/src/main/java/com/endoflineblog/truffle/part_13/exceptions/BreakException.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_13.exceptions; 2 | 3 | import com.oracle.truffle.api.nodes.ControlFlowException; 4 | 5 | /** 6 | * The exception used to implement the {@code break} statement. 7 | * Identical to the class with the same name from part 12. 8 | * 9 | * @see com.endoflineblog.truffle.part_13.nodes.stmts.controlflow.BreakStmtNode 10 | */ 11 | public final class BreakException extends ControlFlowException { 12 | } 13 | -------------------------------------------------------------------------------- /part-14/src/main/java/com/endoflineblog/truffle/part_14/exceptions/BreakException.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_14.exceptions; 2 | 3 | import com.oracle.truffle.api.nodes.ControlFlowException; 4 | 5 | /** 6 | * The exception used to implement the {@code break} statement. 7 | * Identical to the class with the same name from part 13. 8 | * 9 | * @see com.endoflineblog.truffle.part_14.nodes.stmts.controlflow.BreakStmtNode 10 | */ 11 | public final class BreakException extends ControlFlowException { 12 | } 13 | -------------------------------------------------------------------------------- /part-15/src/main/java/com/endoflineblog/truffle/part_15/exceptions/BreakException.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_15.exceptions; 2 | 3 | import com.oracle.truffle.api.nodes.ControlFlowException; 4 | 5 | /** 6 | * The exception used to implement the {@code break} statement. 7 | * Identical to the class with the same name from part 14. 8 | * 9 | * @see com.endoflineblog.truffle.part_15.nodes.stmts.controlflow.BreakStmtNode 10 | */ 11 | public final class BreakException extends ControlFlowException { 12 | } 13 | -------------------------------------------------------------------------------- /part-16/src/main/java/com/endoflineblog/truffle/part_16/exceptions/BreakException.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_16.exceptions; 2 | 3 | import com.oracle.truffle.api.nodes.ControlFlowException; 4 | 5 | /** 6 | * The exception used to implement the {@code break} statement. 7 | * Identical to the class with the same name from part 15. 8 | * 9 | * @see com.endoflineblog.truffle.part_16.nodes.stmts.controlflow.BreakStmtNode 10 | */ 11 | public final class BreakException extends ControlFlowException { 12 | } 13 | -------------------------------------------------------------------------------- /part-16/src/main/resources/fibonacci.js: -------------------------------------------------------------------------------- 1 | function fib(unused, num) { 2 | let n1 = 0, n2 = 1; 3 | if (num > 1) { 4 | var i = 1; 5 | while (i < num) { 6 | const next = n1 + n2; 7 | n1 = n2; 8 | n2 = next; 9 | i = i + 1; 10 | } 11 | return n2; 12 | } else { 13 | return Math.abs(num); 14 | } 15 | } 16 | 17 | let fib3; 18 | fib3 = fib("unused", 3); 19 | if (true) { 20 | while (true) { 21 | break; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /part-09/src/main/java/com/endoflineblog/truffle/part_09/exceptions/ContinueException.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_09.exceptions; 2 | 3 | import com.oracle.truffle.api.nodes.ControlFlowException; 4 | 5 | /** 6 | * The exception used to implement the {@code continue} statement. 7 | * Identical to the class with the same name from part 8. 8 | * 9 | * @see com.endoflineblog.truffle.part_09.nodes.stmts.controlflow.ContinueStmtNode 10 | */ 11 | public final class ContinueException extends ControlFlowException { 12 | } 13 | -------------------------------------------------------------------------------- /part-10/src/main/java/com/endoflineblog/truffle/part_10/exceptions/ContinueException.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_10.exceptions; 2 | 3 | import com.oracle.truffle.api.nodes.ControlFlowException; 4 | 5 | /** 6 | * The exception used to implement the {@code continue} statement. 7 | * Identical to the class with the same name from part 9. 8 | * 9 | * @see com.endoflineblog.truffle.part_10.nodes.stmts.controlflow.ContinueStmtNode 10 | */ 11 | public final class ContinueException extends ControlFlowException { 12 | } 13 | -------------------------------------------------------------------------------- /part-11/src/main/java/com/endoflineblog/truffle/part_11/exceptions/ContinueException.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_11.exceptions; 2 | 3 | import com.oracle.truffle.api.nodes.ControlFlowException; 4 | 5 | /** 6 | * The exception used to implement the {@code continue} statement. 7 | * Identical to the class with the same name from part 10. 8 | * 9 | * @see com.endoflineblog.truffle.part_11.nodes.stmts.controlflow.ContinueStmtNode 10 | */ 11 | public final class ContinueException extends ControlFlowException { 12 | } 13 | -------------------------------------------------------------------------------- /part-12/src/main/java/com/endoflineblog/truffle/part_12/exceptions/ContinueException.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_12.exceptions; 2 | 3 | import com.oracle.truffle.api.nodes.ControlFlowException; 4 | 5 | /** 6 | * The exception used to implement the {@code continue} statement. 7 | * Identical to the class with the same name from part 11. 8 | * 9 | * @see com.endoflineblog.truffle.part_12.nodes.stmts.controlflow.ContinueStmtNode 10 | */ 11 | public final class ContinueException extends ControlFlowException { 12 | } 13 | -------------------------------------------------------------------------------- /part-13/src/main/java/com/endoflineblog/truffle/part_13/exceptions/ContinueException.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_13.exceptions; 2 | 3 | import com.oracle.truffle.api.nodes.ControlFlowException; 4 | 5 | /** 6 | * The exception used to implement the {@code continue} statement. 7 | * Identical to the class with the same name from part 12. 8 | * 9 | * @see com.endoflineblog.truffle.part_13.nodes.stmts.controlflow.ContinueStmtNode 10 | */ 11 | public final class ContinueException extends ControlFlowException { 12 | } 13 | -------------------------------------------------------------------------------- /part-14/src/main/java/com/endoflineblog/truffle/part_14/exceptions/ContinueException.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_14.exceptions; 2 | 3 | import com.oracle.truffle.api.nodes.ControlFlowException; 4 | 5 | /** 6 | * The exception used to implement the {@code continue} statement. 7 | * Identical to the class with the same name from part 13. 8 | * 9 | * @see com.endoflineblog.truffle.part_14.nodes.stmts.controlflow.ContinueStmtNode 10 | */ 11 | public final class ContinueException extends ControlFlowException { 12 | } 13 | -------------------------------------------------------------------------------- /part-15/src/main/java/com/endoflineblog/truffle/part_15/exceptions/ContinueException.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_15.exceptions; 2 | 3 | import com.oracle.truffle.api.nodes.ControlFlowException; 4 | 5 | /** 6 | * The exception used to implement the {@code continue} statement. 7 | * Identical to the class with the same name from part 14. 8 | * 9 | * @see com.endoflineblog.truffle.part_15.nodes.stmts.controlflow.ContinueStmtNode 10 | */ 11 | public final class ContinueException extends ControlFlowException { 12 | } 13 | -------------------------------------------------------------------------------- /part-16/src/main/java/com/endoflineblog/truffle/part_16/exceptions/ContinueException.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_16.exceptions; 2 | 3 | import com.oracle.truffle.api.nodes.ControlFlowException; 4 | 5 | /** 6 | * The exception used to implement the {@code continue} statement. 7 | * Identical to the class with the same name from part 15. 8 | * 9 | * @see com.endoflineblog.truffle.part_16.nodes.stmts.controlflow.ContinueStmtNode 10 | */ 11 | public final class ContinueException extends ControlFlowException { 12 | } 13 | -------------------------------------------------------------------------------- /part-08/src/main/java/com/endoflineblog/truffle/part_08/nodes/exprs/BinaryOperationExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_08.nodes.exprs; 2 | 3 | import com.oracle.truffle.api.dsl.NodeChild; 4 | 5 | /** 6 | * The common superclass of all EasyScript expression Nodes that take two arguments. 7 | * Allows us to save having to put the same {@link NodeChild} 8 | * annotations on a bunch of class declarations. 9 | */ 10 | @NodeChild("leftSide") 11 | @NodeChild("rightSide") 12 | public abstract class BinaryOperationExprNode extends EasyScriptExprNode { 13 | } 14 | -------------------------------------------------------------------------------- /part-01/src/main/java/com/endoflineblog/truffle/part_01/IntLiteralNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_01; 2 | 3 | import com.oracle.truffle.api.frame.VirtualFrame; 4 | 5 | /** 6 | * The AST node that represents an integer literal expression in EasyScript. 7 | */ 8 | public final class IntLiteralNode extends EasyScriptNode { 9 | private final int value; 10 | 11 | public IntLiteralNode(int value) { 12 | this.value = value; 13 | } 14 | 15 | @Override 16 | public int executeInt(VirtualFrame frame) { 17 | return this.value; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /part-07/src/main/java/com/endoflineblog/truffle/part_07/EasyScriptTypeSystem.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_07; 2 | 3 | import com.oracle.truffle.api.dsl.ImplicitCast; 4 | import com.oracle.truffle.api.dsl.TypeSystem; 5 | 6 | /** 7 | * The {@link TypeSystem} for EasyScript. 8 | * Identical to the class with the same name from part 6. 9 | */ 10 | @TypeSystem({ 11 | int.class, 12 | double.class, 13 | }) 14 | public abstract class EasyScriptTypeSystem { 15 | @ImplicitCast 16 | public static double castIntToDouble(int value) { 17 | return value; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /part-09/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'antlr' 3 | id 'me.champeau.jmh' version '0.6.6' 4 | } 5 | 6 | dependencies { 7 | implementation "org.graalvm.js:js:$graal_version" 8 | implementation "org.graalvm.truffle:truffle-sl:$graal_version" 9 | antlr "org.antlr:antlr4:$antlr_version" 10 | } 11 | 12 | // required to allow GraalVM to discover our EasyScript language class 13 | test { 14 | jvmArgs '-Dgraalvm.locatorDisabled=true' 15 | } 16 | 17 | String jmhIncludes = findProperty("jmhIncludes") 18 | jmh { 19 | if (jmhIncludes != null) { 20 | includes = [jmhIncludes] 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /part-10/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'antlr' 3 | id 'me.champeau.jmh' version '0.6.6' 4 | } 5 | 6 | dependencies { 7 | antlr "org.antlr:antlr4:$antlr_version" 8 | implementation "org.graalvm.js:js:$graal_version" 9 | implementation "org.graalvm.truffle:truffle-sl:$graal_version" 10 | } 11 | 12 | // required to allow GraalVM to discover our EasyScript language class 13 | test { 14 | jvmArgs '-Dgraalvm.locatorDisabled=true' 15 | } 16 | 17 | String jmhIncludes = findProperty("jmhIncludes") 18 | jmh { 19 | if (jmhIncludes != null) { 20 | includes = [jmhIncludes] 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /part-08/src/main/java/com/endoflineblog/truffle/part_08/nodes/stmts/controlflow/BreakStmtNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_08.nodes.stmts.controlflow; 2 | 3 | import com.endoflineblog.truffle.part_08.exceptions.BreakException; 4 | import com.endoflineblog.truffle.part_08.nodes.stmts.EasyScriptStmtNode; 5 | import com.oracle.truffle.api.frame.VirtualFrame; 6 | 7 | /** A Node representing the {@code break} statement. */ 8 | public final class BreakStmtNode extends EasyScriptStmtNode { 9 | @Override 10 | public Object executeStatement(VirtualFrame frame) { 11 | throw new BreakException(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /part-09/src/main/java/com/endoflineblog/truffle/part_09/EasyScriptTypeSystem.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_09; 2 | 3 | import com.oracle.truffle.api.dsl.ImplicitCast; 4 | import com.oracle.truffle.api.dsl.TypeSystem; 5 | 6 | /** 7 | * The {@link TypeSystem} for EasyScript. 8 | * Identical to the class with the same name from part 8. 9 | */ 10 | @TypeSystem({ 11 | boolean.class, 12 | int.class, 13 | double.class, 14 | }) 15 | public abstract class EasyScriptTypeSystem { 16 | @ImplicitCast 17 | public static double castIntToDouble(int value) { 18 | return value; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /part-09/src/main/java/com/endoflineblog/truffle/part_09/nodes/exprs/BinaryOperationExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_09.nodes.exprs; 2 | 3 | import com.oracle.truffle.api.dsl.NodeChild; 4 | 5 | /** 6 | * The common superclass of all EasyScript expression Nodes that take two arguments. 7 | * Allows us to save having to put the same {@link NodeChild} 8 | * annotations on a bunch of class declarations. 9 | * Identical to the class with the same name from part 8. 10 | */ 11 | @NodeChild("leftSide") 12 | @NodeChild("rightSide") 13 | public abstract class BinaryOperationExprNode extends EasyScriptExprNode { 14 | } 15 | -------------------------------------------------------------------------------- /part-10/src/main/java/com/endoflineblog/truffle/part_10/EasyScriptTypeSystem.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_10; 2 | 3 | import com.oracle.truffle.api.dsl.ImplicitCast; 4 | import com.oracle.truffle.api.dsl.TypeSystem; 5 | 6 | /** 7 | * The {@link TypeSystem} for EasyScript. 8 | * Identical to the class with the same name from part 9. 9 | */ 10 | @TypeSystem({ 11 | boolean.class, 12 | int.class, 13 | double.class, 14 | }) 15 | public abstract class EasyScriptTypeSystem { 16 | @ImplicitCast 17 | public static double castIntToDouble(int value) { 18 | return value; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /part-10/src/main/java/com/endoflineblog/truffle/part_10/nodes/exprs/BinaryOperationExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_10.nodes.exprs; 2 | 3 | import com.oracle.truffle.api.dsl.NodeChild; 4 | 5 | /** 6 | * The common superclass of all EasyScript expression Nodes that take two arguments. 7 | * Allows us to save having to put the same {@link NodeChild} 8 | * annotations on a bunch of class declarations. 9 | * Identical to the class with the same name from part 9. 10 | */ 11 | @NodeChild("leftSide") 12 | @NodeChild("rightSide") 13 | public abstract class BinaryOperationExprNode extends EasyScriptExprNode { 14 | } 15 | -------------------------------------------------------------------------------- /part-11/src/main/java/com/endoflineblog/truffle/part_11/EasyScriptTypeSystem.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_11; 2 | 3 | import com.oracle.truffle.api.dsl.ImplicitCast; 4 | import com.oracle.truffle.api.dsl.TypeSystem; 5 | 6 | /** 7 | * The {@link TypeSystem} for EasyScript. 8 | * Identical to the class with the same name from part 10. 9 | */ 10 | @TypeSystem({ 11 | boolean.class, 12 | int.class, 13 | double.class, 14 | }) 15 | public abstract class EasyScriptTypeSystem { 16 | @ImplicitCast 17 | public static double castIntToDouble(int value) { 18 | return value; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /part-11/src/main/java/com/endoflineblog/truffle/part_11/nodes/exprs/BinaryOperationExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_11.nodes.exprs; 2 | 3 | import com.oracle.truffle.api.dsl.NodeChild; 4 | 5 | /** 6 | * The common superclass of all EasyScript expression Nodes that take two arguments. 7 | * Allows us to save having to put the same {@link NodeChild} 8 | * annotations on a bunch of class declarations. 9 | * Identical to the class with the same name from part 10. 10 | */ 11 | @NodeChild("leftSide") 12 | @NodeChild("rightSide") 13 | public abstract class BinaryOperationExprNode extends EasyScriptExprNode { 14 | } 15 | -------------------------------------------------------------------------------- /part-12/src/main/java/com/endoflineblog/truffle/part_12/EasyScriptTypeSystem.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_12; 2 | 3 | import com.oracle.truffle.api.dsl.ImplicitCast; 4 | import com.oracle.truffle.api.dsl.TypeSystem; 5 | 6 | /** 7 | * The {@link TypeSystem} for EasyScript. 8 | * Identical to the class with the same name from part 11. 9 | */ 10 | @TypeSystem({ 11 | boolean.class, 12 | int.class, 13 | double.class, 14 | }) 15 | public abstract class EasyScriptTypeSystem { 16 | @ImplicitCast 17 | public static double castIntToDouble(int value) { 18 | return value; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /part-12/src/main/java/com/endoflineblog/truffle/part_12/nodes/exprs/BinaryOperationExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_12.nodes.exprs; 2 | 3 | import com.oracle.truffle.api.dsl.NodeChild; 4 | 5 | /** 6 | * The common superclass of all EasyScript expression Nodes that take two arguments. 7 | * Allows us to save having to put the same {@link NodeChild} 8 | * annotations on a bunch of class declarations. 9 | * Identical to the class with the same name from part 11. 10 | */ 11 | @NodeChild("leftSide") 12 | @NodeChild("rightSide") 13 | public abstract class BinaryOperationExprNode extends EasyScriptExprNode { 14 | } 15 | -------------------------------------------------------------------------------- /part-13/src/main/java/com/endoflineblog/truffle/part_13/EasyScriptTypeSystem.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_13; 2 | 3 | import com.oracle.truffle.api.dsl.ImplicitCast; 4 | import com.oracle.truffle.api.dsl.TypeSystem; 5 | 6 | /** 7 | * The {@link TypeSystem} for EasyScript. 8 | * Identical to the class with the same name from part 12. 9 | */ 10 | @TypeSystem({ 11 | boolean.class, 12 | int.class, 13 | double.class, 14 | }) 15 | public abstract class EasyScriptTypeSystem { 16 | @ImplicitCast 17 | public static double castIntToDouble(int value) { 18 | return value; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /part-13/src/main/java/com/endoflineblog/truffle/part_13/nodes/exprs/BinaryOperationExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_13.nodes.exprs; 2 | 3 | import com.oracle.truffle.api.dsl.NodeChild; 4 | 5 | /** 6 | * The common superclass of all EasyScript expression Nodes that take two arguments. 7 | * Allows us to save having to put the same {@link NodeChild} 8 | * annotations on a bunch of class declarations. 9 | * Identical to the class with the same name from part 12. 10 | */ 11 | @NodeChild("leftSide") 12 | @NodeChild("rightSide") 13 | public abstract class BinaryOperationExprNode extends EasyScriptExprNode { 14 | } 15 | -------------------------------------------------------------------------------- /part-14/src/main/java/com/endoflineblog/truffle/part_14/EasyScriptTypeSystem.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_14; 2 | 3 | import com.oracle.truffle.api.dsl.ImplicitCast; 4 | import com.oracle.truffle.api.dsl.TypeSystem; 5 | 6 | /** 7 | * The {@link TypeSystem} for EasyScript. 8 | * Identical to the class with the same name from part 13. 9 | */ 10 | @TypeSystem({ 11 | boolean.class, 12 | int.class, 13 | double.class, 14 | }) 15 | public abstract class EasyScriptTypeSystem { 16 | @ImplicitCast 17 | public static double castIntToDouble(int value) { 18 | return value; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /part-14/src/main/java/com/endoflineblog/truffle/part_14/nodes/exprs/BinaryOperationExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_14.nodes.exprs; 2 | 3 | import com.oracle.truffle.api.dsl.NodeChild; 4 | 5 | /** 6 | * The common superclass of all EasyScript expression Nodes that take two arguments. 7 | * Allows us to save having to put the same {@link NodeChild} 8 | * annotations on a bunch of class declarations. 9 | * Identical to the class with the same name from part 13. 10 | */ 11 | @NodeChild("leftSide") 12 | @NodeChild("rightSide") 13 | public abstract class BinaryOperationExprNode extends EasyScriptExprNode { 14 | } 15 | -------------------------------------------------------------------------------- /part-15/src/main/java/com/endoflineblog/truffle/part_15/EasyScriptTypeSystem.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_15; 2 | 3 | import com.oracle.truffle.api.dsl.ImplicitCast; 4 | import com.oracle.truffle.api.dsl.TypeSystem; 5 | 6 | /** 7 | * The {@link TypeSystem} for EasyScript. 8 | * Identical to the class with the same name from part 14. 9 | */ 10 | @TypeSystem({ 11 | boolean.class, 12 | int.class, 13 | double.class, 14 | }) 15 | public abstract class EasyScriptTypeSystem { 16 | @ImplicitCast 17 | public static double castIntToDouble(int value) { 18 | return value; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /part-15/src/main/java/com/endoflineblog/truffle/part_15/nodes/exprs/BinaryOperationExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_15.nodes.exprs; 2 | 3 | import com.oracle.truffle.api.dsl.NodeChild; 4 | 5 | /** 6 | * The common superclass of all EasyScript expression Nodes that take two arguments. 7 | * Allows us to save having to put the same {@link NodeChild} 8 | * annotations on a bunch of class declarations. 9 | * Identical to the class with the same name from part 14. 10 | */ 11 | @NodeChild("leftSide") 12 | @NodeChild("rightSide") 13 | public abstract class BinaryOperationExprNode extends EasyScriptExprNode { 14 | } 15 | -------------------------------------------------------------------------------- /part-16/src/main/java/com/endoflineblog/truffle/part_16/EasyScriptTypeSystem.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_16; 2 | 3 | import com.oracle.truffle.api.dsl.ImplicitCast; 4 | import com.oracle.truffle.api.dsl.TypeSystem; 5 | 6 | /** 7 | * The {@link TypeSystem} for EasyScript. 8 | * Identical to the class with the same name from part 15. 9 | */ 10 | @TypeSystem({ 11 | boolean.class, 12 | int.class, 13 | double.class, 14 | }) 15 | public abstract class EasyScriptTypeSystem { 16 | @ImplicitCast 17 | public static double castIntToDouble(int value) { 18 | return value; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /part-16/src/main/java/com/endoflineblog/truffle/part_16/nodes/exprs/BinaryOperationExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_16.nodes.exprs; 2 | 3 | import com.oracle.truffle.api.dsl.NodeChild; 4 | 5 | /** 6 | * The common superclass of all EasyScript expression Nodes that take two arguments. 7 | * Allows us to save having to put the same {@link NodeChild} 8 | * annotations on a bunch of class declarations. 9 | * Identical to the class with the same name from part 15. 10 | */ 11 | @NodeChild("leftSide") 12 | @NodeChild("rightSide") 13 | public abstract class BinaryOperationExprNode extends EasyScriptExprNode { 14 | } 15 | -------------------------------------------------------------------------------- /part-08/src/main/java/com/endoflineblog/truffle/part_08/nodes/stmts/controlflow/ContinueStmtNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_08.nodes.stmts.controlflow; 2 | 3 | import com.endoflineblog.truffle.part_08.exceptions.ContinueException; 4 | import com.endoflineblog.truffle.part_08.nodes.stmts.EasyScriptStmtNode; 5 | import com.oracle.truffle.api.frame.VirtualFrame; 6 | 7 | /** A Node representing the {@code continue} statement. */ 8 | public final class ContinueStmtNode extends EasyScriptStmtNode { 9 | @Override 10 | public Object executeStatement(VirtualFrame frame) { 11 | throw new ContinueException(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /.github/workflows/build.yaml: -------------------------------------------------------------------------------- 1 | name: Build 2 | 3 | on: [ push ] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | env: 9 | # disable the demon, as it's causing some problems 10 | GRADLE_OPTS: -Dorg.gradle.daemon=false 11 | 12 | steps: 13 | - uses: actions/checkout@v2 14 | 15 | - name: Set up GraalVM with Java 11 16 | uses: graalvm/setup-graalvm@v1 17 | with: 18 | version: '22.3.0' 19 | java-version: '11' 20 | 21 | - name: Cache Gradle packages 22 | uses: gradle/actions/setup-gradle@v4 23 | 24 | - name: Build and test the project (all parts) 25 | run: ./gradlew build 26 | -------------------------------------------------------------------------------- /part-08/src/main/java/com/endoflineblog/truffle/part_08/exceptions/ReturnException.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_08.exceptions; 2 | 3 | import com.oracle.truffle.api.nodes.ControlFlowException; 4 | 5 | /** 6 | * The exception used to implement the {@code return} statement. 7 | * 8 | * @see com.endoflineblog.truffle.part_08.nodes.stmts.controlflow.ReturnStmtNode 9 | */ 10 | public final class ReturnException extends ControlFlowException { 11 | /** The value to return from the function. */ 12 | public final Object returnValue; 13 | 14 | public ReturnException(Object returnValue) { 15 | this.returnValue = returnValue; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /part-11/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'antlr' 3 | id 'me.champeau.jmh' version '0.6.6' 4 | } 5 | 6 | dependencies { 7 | antlr "org.antlr:antlr4:$antlr_version" 8 | implementation "org.graalvm.js:js:$graal_version" 9 | implementation "org.graalvm.tools:profiler:$graal_version" 10 | implementation "org.apache.commons:commons-text:1.14.0" 11 | } 12 | 13 | // required to allow GraalVM to discover our EasyScript language class 14 | test { 15 | jvmArgs '-Dgraalvm.locatorDisabled=true' 16 | } 17 | 18 | String jmhIncludes = findProperty("jmhIncludes") 19 | jmh { 20 | if (jmhIncludes != null) { 21 | includes = [jmhIncludes] 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /part-12/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'antlr' 3 | id 'me.champeau.jmh' version '0.6.6' 4 | } 5 | 6 | dependencies { 7 | antlr "org.antlr:antlr4:$antlr_version" 8 | implementation "org.graalvm.js:js:$graal_version" 9 | implementation "org.graalvm.tools:profiler:$graal_version" 10 | implementation "org.apache.commons:commons-text:1.14.0" 11 | } 12 | 13 | // required to allow GraalVM to discover our EasyScript language class 14 | test { 15 | jvmArgs '-Dgraalvm.locatorDisabled=true' 16 | } 17 | 18 | String jmhIncludes = findProperty("jmhIncludes") 19 | jmh { 20 | if (jmhIncludes != null) { 21 | includes = [jmhIncludes] 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /part-13/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'antlr' 3 | id 'me.champeau.jmh' version '0.6.6' 4 | } 5 | 6 | dependencies { 7 | antlr "org.antlr:antlr4:$antlr_version" 8 | implementation "org.graalvm.js:js:$graal_version" 9 | implementation "org.graalvm.tools:profiler:$graal_version" 10 | implementation "org.apache.commons:commons-text:1.14.0" 11 | } 12 | 13 | // required to allow GraalVM to discover our EasyScript language class 14 | test { 15 | jvmArgs '-Dgraalvm.locatorDisabled=true' 16 | } 17 | 18 | String jmhIncludes = findProperty("jmhIncludes") 19 | jmh { 20 | if (jmhIncludes != null) { 21 | includes = [jmhIncludes] 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /part-14/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'antlr' 3 | id 'me.champeau.jmh' version '0.6.6' 4 | } 5 | 6 | dependencies { 7 | antlr "org.antlr:antlr4:$antlr_version" 8 | implementation "org.graalvm.js:js:$graal_version" 9 | implementation "org.graalvm.tools:profiler:$graal_version" 10 | implementation "org.apache.commons:commons-text:1.14.0" 11 | } 12 | 13 | // required to allow GraalVM to discover our EasyScript language class 14 | test { 15 | jvmArgs '-Dgraalvm.locatorDisabled=true' 16 | } 17 | 18 | String jmhIncludes = findProperty("jmhIncludes") 19 | jmh { 20 | if (jmhIncludes != null) { 21 | includes = [jmhIncludes] 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /part-15/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'antlr' 3 | id 'me.champeau.jmh' version '0.6.6' 4 | } 5 | 6 | dependencies { 7 | antlr "org.antlr:antlr4:$antlr_version" 8 | implementation "org.graalvm.js:js:$graal_version" 9 | implementation "org.graalvm.tools:profiler:$graal_version" 10 | implementation "org.apache.commons:commons-text:1.14.0" 11 | } 12 | 13 | // required to allow GraalVM to discover our EasyScript language class 14 | test { 15 | jvmArgs '-Dgraalvm.locatorDisabled=true' 16 | } 17 | 18 | String jmhIncludes = findProperty("jmhIncludes") 19 | jmh { 20 | if (jmhIncludes != null) { 21 | includes = [jmhIncludes] 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /part-05/src/main/java/com/endoflineblog/truffle/part_05/nodes/stmts/EasyScriptStmtNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_05.nodes.stmts; 2 | 3 | import com.endoflineblog.truffle.part_05.nodes.EasyScriptNode; 4 | import com.oracle.truffle.api.frame.VirtualFrame; 5 | 6 | /** 7 | * The abstract common ancestor of all AST Nodes that represent statements in EasyScript, 8 | * like declaring a variable or constant. 9 | */ 10 | public abstract class EasyScriptStmtNode extends EasyScriptNode { 11 | /** 12 | * Evaluates this statement, and returns the result of executing it. 13 | */ 14 | public abstract Object executeStatement(VirtualFrame frame); 15 | } 16 | -------------------------------------------------------------------------------- /part-05/src/main/java/com/endoflineblog/truffle/part_05/nodes/EasyScriptNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_05.nodes; 2 | 3 | import com.endoflineblog.truffle.part_05.EasyScriptLanguageContext; 4 | import com.oracle.truffle.api.nodes.Node; 5 | 6 | /** 7 | * The abstract common ancestor of all EasyScript AST Truffle Nodes. 8 | * 9 | * @see #currentLanguageContext() 10 | */ 11 | public abstract class EasyScriptNode extends Node { 12 | /** Allows retrieving the current Truffle language Context from within a Node. */ 13 | protected final EasyScriptLanguageContext currentLanguageContext() { 14 | return EasyScriptLanguageContext.get(this); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /part-06/src/main/java/com/endoflineblog/truffle/part_06/nodes/EasyScriptNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_06.nodes; 2 | 3 | import com.endoflineblog.truffle.part_06.EasyScriptLanguageContext; 4 | import com.oracle.truffle.api.nodes.Node; 5 | 6 | /** 7 | * The abstract common ancestor of all EasyScript AST Truffle Nodes. 8 | * Identical to the class with the same name from part 5. 9 | */ 10 | public abstract class EasyScriptNode extends Node { 11 | /** Allows retrieving the current Truffle language Context from within a Node. */ 12 | protected final EasyScriptLanguageContext currentLanguageContext() { 13 | return EasyScriptLanguageContext.get(this); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /part-13/src/main/java/com/endoflineblog/truffle/part_13/nodes/exprs/objects/ThisExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_13.nodes.exprs.objects; 2 | 3 | import com.endoflineblog.truffle.part_13.nodes.exprs.EasyScriptExprNode; 4 | import com.oracle.truffle.api.frame.VirtualFrame; 5 | 6 | /** 7 | * The Node implementing the 'this' expression. 8 | */ 9 | public final class ThisExprNode extends EasyScriptExprNode { 10 | @Override 11 | public Object executeGeneric(VirtualFrame frame) { 12 | // because of how we handle calls in FunctionDispatchNode, 13 | // the `this` object is always in the first argument 14 | return frame.getArguments()[0]; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /part-09/src/main/java/com/endoflineblog/truffle/part_09/nodes/stmts/controlflow/BreakStmtNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_09.nodes.stmts.controlflow; 2 | 3 | import com.endoflineblog.truffle.part_09.exceptions.BreakException; 4 | import com.endoflineblog.truffle.part_09.nodes.stmts.EasyScriptStmtNode; 5 | import com.oracle.truffle.api.frame.VirtualFrame; 6 | 7 | /** 8 | * A Node representing the {@code break} statement. 9 | * Identical to the class with the same name from part 8. 10 | */ 11 | public final class BreakStmtNode extends EasyScriptStmtNode { 12 | @Override 13 | public Object executeStatement(VirtualFrame frame) { 14 | throw new BreakException(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /part-10/src/main/java/com/endoflineblog/truffle/part_10/nodes/stmts/controlflow/BreakStmtNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_10.nodes.stmts.controlflow; 2 | 3 | import com.endoflineblog.truffle.part_10.exceptions.BreakException; 4 | import com.endoflineblog.truffle.part_10.nodes.stmts.EasyScriptStmtNode; 5 | import com.oracle.truffle.api.frame.VirtualFrame; 6 | 7 | /** 8 | * A Node representing the {@code break} statement. 9 | * Identical to the class with the same name from part 9. 10 | */ 11 | public final class BreakStmtNode extends EasyScriptStmtNode { 12 | @Override 13 | public Object executeStatement(VirtualFrame frame) { 14 | throw new BreakException(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /part-11/src/main/java/com/endoflineblog/truffle/part_11/nodes/stmts/controlflow/BreakStmtNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_11.nodes.stmts.controlflow; 2 | 3 | import com.endoflineblog.truffle.part_11.exceptions.BreakException; 4 | import com.endoflineblog.truffle.part_11.nodes.stmts.EasyScriptStmtNode; 5 | import com.oracle.truffle.api.frame.VirtualFrame; 6 | 7 | /** 8 | * A Node representing the {@code break} statement. 9 | * Identical to the class with the same name from part 10. 10 | */ 11 | public final class BreakStmtNode extends EasyScriptStmtNode { 12 | @Override 13 | public Object executeStatement(VirtualFrame frame) { 14 | throw new BreakException(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /part-12/src/main/java/com/endoflineblog/truffle/part_12/nodes/stmts/controlflow/BreakStmtNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_12.nodes.stmts.controlflow; 2 | 3 | import com.endoflineblog.truffle.part_12.exceptions.BreakException; 4 | import com.endoflineblog.truffle.part_12.nodes.stmts.EasyScriptStmtNode; 5 | import com.oracle.truffle.api.frame.VirtualFrame; 6 | 7 | /** 8 | * A Node representing the {@code break} statement. 9 | * Identical to the class with the same name from part 11. 10 | */ 11 | public final class BreakStmtNode extends EasyScriptStmtNode { 12 | @Override 13 | public Object executeStatement(VirtualFrame frame) { 14 | throw new BreakException(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /part-13/src/main/java/com/endoflineblog/truffle/part_13/nodes/stmts/controlflow/BreakStmtNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_13.nodes.stmts.controlflow; 2 | 3 | import com.endoflineblog.truffle.part_13.exceptions.BreakException; 4 | import com.endoflineblog.truffle.part_13.nodes.stmts.EasyScriptStmtNode; 5 | import com.oracle.truffle.api.frame.VirtualFrame; 6 | 7 | /** 8 | * A Node representing the {@code break} statement. 9 | * Identical to the class with the same name from part 12. 10 | */ 11 | public final class BreakStmtNode extends EasyScriptStmtNode { 12 | @Override 13 | public Object executeStatement(VirtualFrame frame) { 14 | throw new BreakException(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /part-14/src/main/java/com/endoflineblog/truffle/part_14/nodes/stmts/controlflow/BreakStmtNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_14.nodes.stmts.controlflow; 2 | 3 | import com.endoflineblog.truffle.part_14.exceptions.BreakException; 4 | import com.endoflineblog.truffle.part_14.nodes.stmts.EasyScriptStmtNode; 5 | import com.oracle.truffle.api.frame.VirtualFrame; 6 | 7 | /** 8 | * A Node representing the {@code break} statement. 9 | * Identical to the class with the same name from part 13. 10 | */ 11 | public final class BreakStmtNode extends EasyScriptStmtNode { 12 | @Override 13 | public Object executeStatement(VirtualFrame frame) { 14 | throw new BreakException(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /part-15/src/main/java/com/endoflineblog/truffle/part_15/nodes/stmts/controlflow/BreakStmtNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_15.nodes.stmts.controlflow; 2 | 3 | import com.endoflineblog.truffle.part_15.exceptions.BreakException; 4 | import com.endoflineblog.truffle.part_15.nodes.stmts.EasyScriptStmtNode; 5 | import com.oracle.truffle.api.frame.VirtualFrame; 6 | 7 | /** 8 | * A Node representing the {@code break} statement. 9 | * Identical to the class with the same name from part 14. 10 | */ 11 | public final class BreakStmtNode extends EasyScriptStmtNode { 12 | @Override 13 | public Object executeStatement(VirtualFrame frame) { 14 | throw new BreakException(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /part-09/src/main/java/com/endoflineblog/truffle/part_09/nodes/stmts/controlflow/ContinueStmtNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_09.nodes.stmts.controlflow; 2 | 3 | import com.endoflineblog.truffle.part_09.exceptions.ContinueException; 4 | import com.endoflineblog.truffle.part_09.nodes.stmts.EasyScriptStmtNode; 5 | import com.oracle.truffle.api.frame.VirtualFrame; 6 | 7 | /** 8 | * A Node representing the {@code continue} statement. 9 | * Identical to the class with the same name from part 8. 10 | */ 11 | public final class ContinueStmtNode extends EasyScriptStmtNode { 12 | @Override 13 | public Object executeStatement(VirtualFrame frame) { 14 | throw new ContinueException(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /part-10/src/main/java/com/endoflineblog/truffle/part_10/nodes/stmts/controlflow/ContinueStmtNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_10.nodes.stmts.controlflow; 2 | 3 | import com.endoflineblog.truffle.part_10.exceptions.ContinueException; 4 | import com.endoflineblog.truffle.part_10.nodes.stmts.EasyScriptStmtNode; 5 | import com.oracle.truffle.api.frame.VirtualFrame; 6 | 7 | /** 8 | * A Node representing the {@code continue} statement. 9 | * Identical to the class with the same name from part 9. 10 | */ 11 | public final class ContinueStmtNode extends EasyScriptStmtNode { 12 | @Override 13 | public Object executeStatement(VirtualFrame frame) { 14 | throw new ContinueException(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /part-11/src/main/java/com/endoflineblog/truffle/part_11/nodes/stmts/controlflow/ContinueStmtNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_11.nodes.stmts.controlflow; 2 | 3 | import com.endoflineblog.truffle.part_11.exceptions.ContinueException; 4 | import com.endoflineblog.truffle.part_11.nodes.stmts.EasyScriptStmtNode; 5 | import com.oracle.truffle.api.frame.VirtualFrame; 6 | 7 | /** 8 | * A Node representing the {@code continue} statement. 9 | * Identical to the class with the same name from part 10. 10 | */ 11 | public final class ContinueStmtNode extends EasyScriptStmtNode { 12 | @Override 13 | public Object executeStatement(VirtualFrame frame) { 14 | throw new ContinueException(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /part-12/src/main/java/com/endoflineblog/truffle/part_12/nodes/stmts/controlflow/ContinueStmtNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_12.nodes.stmts.controlflow; 2 | 3 | import com.endoflineblog.truffle.part_12.exceptions.ContinueException; 4 | import com.endoflineblog.truffle.part_12.nodes.stmts.EasyScriptStmtNode; 5 | import com.oracle.truffle.api.frame.VirtualFrame; 6 | 7 | /** 8 | * A Node representing the {@code continue} statement. 9 | * Identical to the class with the same name from part 11. 10 | */ 11 | public final class ContinueStmtNode extends EasyScriptStmtNode { 12 | @Override 13 | public Object executeStatement(VirtualFrame frame) { 14 | throw new ContinueException(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /part-13/src/main/java/com/endoflineblog/truffle/part_13/nodes/stmts/controlflow/ContinueStmtNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_13.nodes.stmts.controlflow; 2 | 3 | import com.endoflineblog.truffle.part_13.exceptions.ContinueException; 4 | import com.endoflineblog.truffle.part_13.nodes.stmts.EasyScriptStmtNode; 5 | import com.oracle.truffle.api.frame.VirtualFrame; 6 | 7 | /** 8 | * A Node representing the {@code continue} statement. 9 | * Identical to the class with the same name from part 12. 10 | */ 11 | public final class ContinueStmtNode extends EasyScriptStmtNode { 12 | @Override 13 | public Object executeStatement(VirtualFrame frame) { 14 | throw new ContinueException(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /part-14/src/main/java/com/endoflineblog/truffle/part_14/nodes/stmts/controlflow/ContinueStmtNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_14.nodes.stmts.controlflow; 2 | 3 | import com.endoflineblog.truffle.part_14.exceptions.ContinueException; 4 | import com.endoflineblog.truffle.part_14.nodes.stmts.EasyScriptStmtNode; 5 | import com.oracle.truffle.api.frame.VirtualFrame; 6 | 7 | /** 8 | * A Node representing the {@code continue} statement. 9 | * Identical to the class with the same name from part 13. 10 | */ 11 | public final class ContinueStmtNode extends EasyScriptStmtNode { 12 | @Override 13 | public Object executeStatement(VirtualFrame frame) { 14 | throw new ContinueException(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /part-15/src/main/java/com/endoflineblog/truffle/part_15/nodes/stmts/controlflow/ContinueStmtNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_15.nodes.stmts.controlflow; 2 | 3 | import com.endoflineblog.truffle.part_15.exceptions.ContinueException; 4 | import com.endoflineblog.truffle.part_15.nodes.stmts.EasyScriptStmtNode; 5 | import com.oracle.truffle.api.frame.VirtualFrame; 6 | 7 | /** 8 | * A Node representing the {@code continue} statement. 9 | * Identical to the class with the same name from part 14. 10 | */ 11 | public final class ContinueStmtNode extends EasyScriptStmtNode { 12 | @Override 13 | public Object executeStatement(VirtualFrame frame) { 14 | throw new ContinueException(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /part-06/src/main/java/com/endoflineblog/truffle/part_06/EasyScriptException.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_06; 2 | 3 | import com.oracle.truffle.api.exception.AbstractTruffleException; 4 | import com.oracle.truffle.api.nodes.Node; 5 | 6 | /** 7 | * The exception that's thrown from the EasyScript implementation if any semantic errors are found. 8 | * Identical to the class with the same name from part 5. 9 | */ 10 | public final class EasyScriptException extends AbstractTruffleException { 11 | public EasyScriptException(String message) { 12 | this(null, message); 13 | } 14 | 15 | public EasyScriptException(Node location, String message) { 16 | super(message, location); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /part-07/src/main/java/com/endoflineblog/truffle/part_07/EasyScriptException.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_07; 2 | 3 | import com.oracle.truffle.api.exception.AbstractTruffleException; 4 | import com.oracle.truffle.api.nodes.Node; 5 | 6 | /** 7 | * The exception that's thrown from the EasyScript implementation if any semantic errors are found. 8 | * Identical to the class with the same name from part 6. 9 | */ 10 | public final class EasyScriptException extends AbstractTruffleException { 11 | public EasyScriptException(String message) { 12 | this(null, message); 13 | } 14 | 15 | public EasyScriptException(Node location, String message) { 16 | super(message, location); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /part-08/src/main/java/com/endoflineblog/truffle/part_08/EasyScriptTypeSystem.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_08; 2 | 3 | import com.oracle.truffle.api.dsl.ImplicitCast; 4 | import com.oracle.truffle.api.dsl.TypeSystem; 5 | 6 | /** 7 | * The {@link TypeSystem} for EasyScript. 8 | * Almost identical to the class with the same name from part 7, 9 | * the only difference is that we add booleans to the hierarchy of EasyScript types. 10 | */ 11 | @TypeSystem({ 12 | boolean.class, 13 | int.class, 14 | double.class, 15 | }) 16 | public abstract class EasyScriptTypeSystem { 17 | @ImplicitCast 18 | public static double castIntToDouble(int value) { 19 | return value; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /part-09/src/main/java/com/endoflineblog/truffle/part_09/exceptions/ReturnException.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_09.exceptions; 2 | 3 | import com.oracle.truffle.api.nodes.ControlFlowException; 4 | 5 | /** 6 | * The exception used to implement the {@code return} statement. 7 | * Identical to the class with the same name from part 8. 8 | * 9 | * @see com.endoflineblog.truffle.part_09.nodes.stmts.controlflow.ReturnStmtNode 10 | */ 11 | public final class ReturnException extends ControlFlowException { 12 | /** The value to return from the function. */ 13 | public final Object returnValue; 14 | 15 | public ReturnException(Object returnValue) { 16 | this.returnValue = returnValue; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /part-10/src/main/java/com/endoflineblog/truffle/part_10/exceptions/ReturnException.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_10.exceptions; 2 | 3 | import com.oracle.truffle.api.nodes.ControlFlowException; 4 | 5 | /** 6 | * The exception used to implement the {@code return} statement. 7 | * Identical to the class with the same name from part 9. 8 | * 9 | * @see com.endoflineblog.truffle.part_10.nodes.stmts.controlflow.ReturnStmtNode 10 | */ 11 | public final class ReturnException extends ControlFlowException { 12 | /** The value to return from the function. */ 13 | public final Object returnValue; 14 | 15 | public ReturnException(Object returnValue) { 16 | this.returnValue = returnValue; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /part-06/src/main/java/com/endoflineblog/truffle/part_06/nodes/stmts/EasyScriptStmtNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_06.nodes.stmts; 2 | 3 | import com.endoflineblog.truffle.part_06.nodes.EasyScriptNode; 4 | import com.oracle.truffle.api.frame.VirtualFrame; 5 | 6 | /** 7 | * The abstract common ancestor of all AST Nodes that represent statements in EasyScript, 8 | * like declaring a variable or constant. 9 | * Identical to the class with the same name from part 5. 10 | */ 11 | public abstract class EasyScriptStmtNode extends EasyScriptNode { 12 | /** 13 | * Evaluates this statement, and returns the result of executing it. 14 | */ 15 | public abstract Object executeStatement(VirtualFrame frame); 16 | } 17 | -------------------------------------------------------------------------------- /part-08/src/main/java/com/endoflineblog/truffle/part_08/nodes/stmts/EasyScriptStmtNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_08.nodes.stmts; 2 | 3 | import com.endoflineblog.truffle.part_08.nodes.EasyScriptNode; 4 | import com.oracle.truffle.api.frame.VirtualFrame; 5 | 6 | /** 7 | * The abstract common ancestor of all AST Nodes that represent statements in EasyScript, 8 | * like declaring a variable or constant. 9 | * Identical to the class with the same name from part 7. 10 | */ 11 | public abstract class EasyScriptStmtNode extends EasyScriptNode { 12 | /** 13 | * Evaluates this statement, and returns the result of executing it. 14 | */ 15 | public abstract Object executeStatement(VirtualFrame frame); 16 | } 17 | -------------------------------------------------------------------------------- /part-09/src/main/java/com/endoflineblog/truffle/part_09/nodes/stmts/EasyScriptStmtNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_09.nodes.stmts; 2 | 3 | import com.endoflineblog.truffle.part_09.nodes.EasyScriptNode; 4 | import com.oracle.truffle.api.frame.VirtualFrame; 5 | 6 | /** 7 | * The abstract common ancestor of all AST Nodes that represent statements in EasyScript, 8 | * like declaring a variable or constant. 9 | * Identical to the class with the same name from part 8. 10 | */ 11 | public abstract class EasyScriptStmtNode extends EasyScriptNode { 12 | /** 13 | * Evaluates this statement, and returns the result of executing it. 14 | */ 15 | public abstract Object executeStatement(VirtualFrame frame); 16 | } 17 | -------------------------------------------------------------------------------- /part-10/src/main/java/com/endoflineblog/truffle/part_10/nodes/stmts/EasyScriptStmtNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_10.nodes.stmts; 2 | 3 | import com.endoflineblog.truffle.part_10.nodes.EasyScriptNode; 4 | import com.oracle.truffle.api.frame.VirtualFrame; 5 | 6 | /** 7 | * The abstract common ancestor of all AST Nodes that represent statements in EasyScript, 8 | * like declaring a variable or constant. 9 | * Identical to the class with the same name from part 9. 10 | */ 11 | public abstract class EasyScriptStmtNode extends EasyScriptNode { 12 | /** 13 | * Evaluates this statement, and returns the result of executing it. 14 | */ 15 | public abstract Object executeStatement(VirtualFrame frame); 16 | } 17 | -------------------------------------------------------------------------------- /part-11/src/main/java/com/endoflineblog/truffle/part_11/exceptions/ReturnException.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_11.exceptions; 2 | 3 | import com.oracle.truffle.api.nodes.ControlFlowException; 4 | 5 | /** 6 | * The exception used to implement the {@code return} statement. 7 | * Identical to the class with the same name from part 10. 8 | * 9 | * @see com.endoflineblog.truffle.part_11.nodes.stmts.controlflow.ReturnStmtNode 10 | */ 11 | public final class ReturnException extends ControlFlowException { 12 | /** The value to return from the function. */ 13 | public final Object returnValue; 14 | 15 | public ReturnException(Object returnValue) { 16 | this.returnValue = returnValue; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /part-11/src/main/java/com/endoflineblog/truffle/part_11/nodes/stmts/EasyScriptStmtNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_11.nodes.stmts; 2 | 3 | import com.endoflineblog.truffle.part_11.nodes.EasyScriptNode; 4 | import com.oracle.truffle.api.frame.VirtualFrame; 5 | 6 | /** 7 | * The abstract common ancestor of all AST Nodes that represent statements in EasyScript, 8 | * like declaring a variable or constant. 9 | * Identical to the class with the same name from part 10. 10 | */ 11 | public abstract class EasyScriptStmtNode extends EasyScriptNode { 12 | /** 13 | * Evaluates this statement, and returns the result of executing it. 14 | */ 15 | public abstract Object executeStatement(VirtualFrame frame); 16 | } 17 | -------------------------------------------------------------------------------- /part-12/src/main/java/com/endoflineblog/truffle/part_12/exceptions/ReturnException.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_12.exceptions; 2 | 3 | import com.oracle.truffle.api.nodes.ControlFlowException; 4 | 5 | /** 6 | * The exception used to implement the {@code return} statement. 7 | * Identical to the class with the same name from part 11. 8 | * 9 | * @see com.endoflineblog.truffle.part_12.nodes.stmts.controlflow.ReturnStmtNode 10 | */ 11 | public final class ReturnException extends ControlFlowException { 12 | /** The value to return from the function. */ 13 | public final Object returnValue; 14 | 15 | public ReturnException(Object returnValue) { 16 | this.returnValue = returnValue; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /part-12/src/main/java/com/endoflineblog/truffle/part_12/nodes/stmts/EasyScriptStmtNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_12.nodes.stmts; 2 | 3 | import com.endoflineblog.truffle.part_12.nodes.EasyScriptNode; 4 | import com.oracle.truffle.api.frame.VirtualFrame; 5 | 6 | /** 7 | * The abstract common ancestor of all AST Nodes that represent statements in EasyScript, 8 | * like declaring a variable or constant. 9 | * Identical to the class with the same name from part 11. 10 | */ 11 | public abstract class EasyScriptStmtNode extends EasyScriptNode { 12 | /** 13 | * Evaluates this statement, and returns the result of executing it. 14 | */ 15 | public abstract Object executeStatement(VirtualFrame frame); 16 | } 17 | -------------------------------------------------------------------------------- /part-13/src/main/java/com/endoflineblog/truffle/part_13/exceptions/ReturnException.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_13.exceptions; 2 | 3 | import com.oracle.truffle.api.nodes.ControlFlowException; 4 | 5 | /** 6 | * The exception used to implement the {@code return} statement. 7 | * Identical to the class with the same name from part 12. 8 | * 9 | * @see com.endoflineblog.truffle.part_13.nodes.stmts.controlflow.ReturnStmtNode 10 | */ 11 | public final class ReturnException extends ControlFlowException { 12 | /** The value to return from the function. */ 13 | public final Object returnValue; 14 | 15 | public ReturnException(Object returnValue) { 16 | this.returnValue = returnValue; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /part-13/src/main/java/com/endoflineblog/truffle/part_13/nodes/stmts/EasyScriptStmtNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_13.nodes.stmts; 2 | 3 | import com.endoflineblog.truffle.part_13.nodes.EasyScriptNode; 4 | import com.oracle.truffle.api.frame.VirtualFrame; 5 | 6 | /** 7 | * The abstract common ancestor of all AST Nodes that represent statements in EasyScript, 8 | * like declaring a variable or constant. 9 | * Identical to the class with the same name from part 12. 10 | */ 11 | public abstract class EasyScriptStmtNode extends EasyScriptNode { 12 | /** 13 | * Evaluates this statement, and returns the result of executing it. 14 | */ 15 | public abstract Object executeStatement(VirtualFrame frame); 16 | } 17 | -------------------------------------------------------------------------------- /part-14/src/main/java/com/endoflineblog/truffle/part_14/exceptions/ReturnException.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_14.exceptions; 2 | 3 | import com.oracle.truffle.api.nodes.ControlFlowException; 4 | 5 | /** 6 | * The exception used to implement the {@code return} statement. 7 | * Identical to the class with the same name from part 13. 8 | * 9 | * @see com.endoflineblog.truffle.part_14.nodes.stmts.controlflow.ReturnStmtNode 10 | */ 11 | public final class ReturnException extends ControlFlowException { 12 | /** The value to return from the function. */ 13 | public final Object returnValue; 14 | 15 | public ReturnException(Object returnValue) { 16 | this.returnValue = returnValue; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /part-14/src/main/java/com/endoflineblog/truffle/part_14/nodes/stmts/EasyScriptStmtNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_14.nodes.stmts; 2 | 3 | import com.endoflineblog.truffle.part_14.nodes.EasyScriptNode; 4 | import com.oracle.truffle.api.frame.VirtualFrame; 5 | 6 | /** 7 | * The abstract common ancestor of all AST Nodes that represent statements in EasyScript, 8 | * like declaring a variable or constant. 9 | * Identical to the class with the same name from part 13. 10 | */ 11 | public abstract class EasyScriptStmtNode extends EasyScriptNode { 12 | /** 13 | * Evaluates this statement, and returns the result of executing it. 14 | */ 15 | public abstract Object executeStatement(VirtualFrame frame); 16 | } 17 | -------------------------------------------------------------------------------- /part-15/src/main/java/com/endoflineblog/truffle/part_15/exceptions/ReturnException.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_15.exceptions; 2 | 3 | import com.oracle.truffle.api.nodes.ControlFlowException; 4 | 5 | /** 6 | * The exception used to implement the {@code return} statement. 7 | * Identical to the class with the same name from part 14. 8 | * 9 | * @see com.endoflineblog.truffle.part_15.nodes.stmts.controlflow.ReturnStmtNode; 10 | */ 11 | public final class ReturnException extends ControlFlowException { 12 | /** The value to return from the function. */ 13 | public final Object returnValue; 14 | 15 | public ReturnException(Object returnValue) { 16 | this.returnValue = returnValue; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /part-15/src/main/java/com/endoflineblog/truffle/part_15/nodes/stmts/EasyScriptStmtNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_15.nodes.stmts; 2 | 3 | import com.endoflineblog.truffle.part_15.nodes.EasyScriptNode; 4 | import com.oracle.truffle.api.frame.VirtualFrame; 5 | 6 | /** 7 | * The abstract common ancestor of all AST Nodes that represent statements in EasyScript, 8 | * like declaring a variable or constant. 9 | * Identical to the class with the same name from part 14. 10 | */ 11 | public abstract class EasyScriptStmtNode extends EasyScriptNode { 12 | /** 13 | * Evaluates this statement, and returns the result of executing it. 14 | */ 15 | public abstract Object executeStatement(VirtualFrame frame); 16 | } 17 | -------------------------------------------------------------------------------- /part-16/src/main/java/com/endoflineblog/truffle/part_16/exceptions/ReturnException.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_16.exceptions; 2 | 3 | import com.oracle.truffle.api.nodes.ControlFlowException; 4 | 5 | /** 6 | * The exception used to implement the {@code return} statement. 7 | * Identical to the class with the same name from part 15. 8 | * 9 | * @see com.endoflineblog.truffle.part_16.nodes.stmts.controlflow.ReturnStmtNode 10 | */ 11 | public final class ReturnException extends ControlFlowException { 12 | /** The value to return from the function. */ 13 | public final Object returnValue; 14 | 15 | public ReturnException(Object returnValue) { 16 | this.returnValue = returnValue; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /part-08/src/main/java/com/endoflineblog/truffle/part_08/exceptions/EasyScriptException.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_08.exceptions; 2 | 3 | import com.oracle.truffle.api.exception.AbstractTruffleException; 4 | import com.oracle.truffle.api.nodes.Node; 5 | 6 | /** 7 | * The exception that's thrown from the EasyScript implementation if any semantic errors are found. 8 | * Identical to the class with the same name from part 7. 9 | */ 10 | public final class EasyScriptException extends AbstractTruffleException { 11 | public EasyScriptException(String message) { 12 | this(null, message); 13 | } 14 | 15 | public EasyScriptException(Node location, String message) { 16 | super(message, location); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /part-09/src/main/java/com/endoflineblog/truffle/part_09/exceptions/EasyScriptException.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_09.exceptions; 2 | 3 | import com.oracle.truffle.api.exception.AbstractTruffleException; 4 | import com.oracle.truffle.api.nodes.Node; 5 | 6 | /** 7 | * The exception that's thrown from the EasyScript implementation if any semantic errors are found. 8 | * Identical to the class with the same name from part 8. 9 | */ 10 | public final class EasyScriptException extends AbstractTruffleException { 11 | public EasyScriptException(String message) { 12 | this(null, message); 13 | } 14 | 15 | public EasyScriptException(Node location, String message) { 16 | super(message, location); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /part-10/src/main/java/com/endoflineblog/truffle/part_10/exceptions/EasyScriptException.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_10.exceptions; 2 | 3 | import com.oracle.truffle.api.exception.AbstractTruffleException; 4 | import com.oracle.truffle.api.nodes.Node; 5 | 6 | /** 7 | * The exception that's thrown from the EasyScript implementation if any semantic errors are found. 8 | * Identical to the class with the same name from part 9. 9 | */ 10 | public final class EasyScriptException extends AbstractTruffleException { 11 | public EasyScriptException(String message) { 12 | this(null, message); 13 | } 14 | 15 | public EasyScriptException(Node location, String message) { 16 | super(message, location); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /part-11/src/main/java/com/endoflineblog/truffle/part_11/exceptions/EasyScriptException.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_11.exceptions; 2 | 3 | import com.oracle.truffle.api.exception.AbstractTruffleException; 4 | import com.oracle.truffle.api.nodes.Node; 5 | 6 | /** 7 | * The exception that's thrown from the EasyScript implementation if any semantic errors are found. 8 | * Identical to the class with the same name from part 10. 9 | */ 10 | public final class EasyScriptException extends AbstractTruffleException { 11 | public EasyScriptException(String message) { 12 | this(null, message); 13 | } 14 | 15 | public EasyScriptException(Node location, String message) { 16 | super(message, location); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /part-12/src/main/java/com/endoflineblog/truffle/part_12/exceptions/EasyScriptException.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_12.exceptions; 2 | 3 | import com.oracle.truffle.api.exception.AbstractTruffleException; 4 | import com.oracle.truffle.api.nodes.Node; 5 | 6 | /** 7 | * The exception that's thrown from the EasyScript implementation if any semantic errors are found. 8 | * Identical to the class with the same name from part 11. 9 | */ 10 | public final class EasyScriptException extends AbstractTruffleException { 11 | public EasyScriptException(String message) { 12 | this(null, message); 13 | } 14 | 15 | public EasyScriptException(Node location, String message) { 16 | super(message, location); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /part-13/src/main/java/com/endoflineblog/truffle/part_13/exceptions/EasyScriptException.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_13.exceptions; 2 | 3 | import com.oracle.truffle.api.exception.AbstractTruffleException; 4 | import com.oracle.truffle.api.nodes.Node; 5 | 6 | /** 7 | * The exception that's thrown from the EasyScript implementation if any semantic errors are found. 8 | * Identical to the class with the same name from part 12. 9 | */ 10 | public final class EasyScriptException extends AbstractTruffleException { 11 | public EasyScriptException(String message) { 12 | this(null, message); 13 | } 14 | 15 | public EasyScriptException(Node location, String message) { 16 | super(message, location); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /part-14/src/main/java/com/endoflineblog/truffle/part_14/exceptions/EasyScriptException.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_14.exceptions; 2 | 3 | import com.oracle.truffle.api.exception.AbstractTruffleException; 4 | import com.oracle.truffle.api.nodes.Node; 5 | 6 | /** 7 | * The exception that's thrown from the EasyScript implementation if any semantic errors are found. 8 | * Identical to the class with the same name from part 13. 9 | */ 10 | public final class EasyScriptException extends AbstractTruffleException { 11 | public EasyScriptException(String message) { 12 | this(null, message); 13 | } 14 | 15 | public EasyScriptException(Node location, String message) { 16 | super(message, location); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /part-14/src/main/java/com/endoflineblog/truffle/part_14/nodes/exprs/objects/ThisExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_14.nodes.exprs.objects; 2 | 3 | import com.endoflineblog.truffle.part_14.nodes.exprs.EasyScriptExprNode; 4 | import com.oracle.truffle.api.frame.VirtualFrame; 5 | 6 | /** 7 | * The Node implementing the 'this' expression. 8 | * Identical to the class with the same name from part 13. 9 | */ 10 | public final class ThisExprNode extends EasyScriptExprNode { 11 | @Override 12 | public Object executeGeneric(VirtualFrame frame) { 13 | // because of how we handle calls in FunctionDispatchNode, 14 | // the `this` object is always in the first argument 15 | return frame.getArguments()[0]; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /part-15/src/main/java/com/endoflineblog/truffle/part_15/nodes/exprs/objects/ThisExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_15.nodes.exprs.objects; 2 | 3 | import com.endoflineblog.truffle.part_15.nodes.exprs.EasyScriptExprNode; 4 | import com.oracle.truffle.api.frame.VirtualFrame; 5 | 6 | /** 7 | * The Node implementing the 'this' expression. 8 | * Identical to the class with the same name from part 14. 9 | */ 10 | public final class ThisExprNode extends EasyScriptExprNode { 11 | @Override 12 | public Object executeGeneric(VirtualFrame frame) { 13 | // because of how we handle calls in FunctionDispatchNode, 14 | // the `this` object is always in the first argument 15 | return frame.getArguments()[0]; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /part-16/src/main/java/com/endoflineblog/truffle/part_16/nodes/exprs/objects/ThisExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_16.nodes.exprs.objects; 2 | 3 | import com.endoflineblog.truffle.part_16.nodes.exprs.EasyScriptExprNode; 4 | import com.oracle.truffle.api.frame.VirtualFrame; 5 | 6 | /** 7 | * The Node implementing the 'this' expression. 8 | * Identical to the class with the same name from part 15. 9 | */ 10 | public final class ThisExprNode extends EasyScriptExprNode { 11 | @Override 12 | public Object executeGeneric(VirtualFrame frame) { 13 | // because of how we handle calls in FunctionDispatchNode, 14 | // the `this` object is always in the first argument 15 | return frame.getArguments()[0]; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /part-07/src/main/java/com/endoflineblog/truffle/part_07/nodes/stmts/EasyScriptStmtNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_07.nodes.stmts; 2 | 3 | import com.endoflineblog.truffle.part_07.nodes.EasyScriptNode; 4 | import com.oracle.truffle.api.frame.VirtualFrame; 5 | import com.oracle.truffle.api.nodes.Node; 6 | 7 | /** 8 | * The abstract common ancestor of all AST Nodes that represent statements in EasyScript, 9 | * like declaring a variable or constant. 10 | * Identical to the class with the same name from part 6. 11 | */ 12 | public abstract class EasyScriptStmtNode extends EasyScriptNode { 13 | /** 14 | * Evaluates this statement, and returns the result of executing it. 15 | */ 16 | public abstract Object executeStatement(VirtualFrame frame); 17 | } 18 | -------------------------------------------------------------------------------- /part-12/src/main/java/com/endoflineblog/truffle/part_12/runtime/StringPrototype.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_12.runtime; 2 | 3 | import com.oracle.truffle.api.CallTarget; 4 | 5 | /** 6 | * The object containing the {@code CallTarget}s 7 | * for the built-in methods of strings. 8 | * Identical to the class with the same name from part 11. 9 | */ 10 | public final class StringPrototype { 11 | /** 12 | * The {@link CallTarget} for the {@code charAt()} string method. 13 | * 14 | * @see com.endoflineblog.truffle.part_12.nodes.exprs.functions.built_in.methods.CharAtMethodBodyExprNode 15 | */ 16 | public final CallTarget charAtMethod; 17 | 18 | public StringPrototype(CallTarget charAtMethod) { 19 | this.charAtMethod = charAtMethod; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /part-02/src/main/java/com/endoflineblog/truffle/part_02/IntLiteralNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_02; 2 | 3 | import com.oracle.truffle.api.frame.VirtualFrame; 4 | 5 | /** 6 | * The AST node that represents an integer literal expression in EasyScript. 7 | */ 8 | public final class IntLiteralNode extends EasyScriptNode { 9 | private final int value; 10 | 11 | public IntLiteralNode(int value) { 12 | this.value = value; 13 | } 14 | 15 | @Override 16 | public int executeInt(VirtualFrame frame) { 17 | return this.value; 18 | } 19 | 20 | @Override 21 | public double executeDouble(VirtualFrame frame) { 22 | return this.value; 23 | } 24 | 25 | @Override 26 | public Object executeGeneric(VirtualFrame frame) { 27 | return this.value; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /part-07/src/main/java/com/endoflineblog/truffle/part_07/nodes/exprs/functions/built_in/BuiltInFunctionBodyExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_07.nodes.exprs.functions.built_in; 2 | 3 | import com.endoflineblog.truffle.part_07.nodes.exprs.EasyScriptExprNode; 4 | import com.endoflineblog.truffle.part_07.nodes.exprs.functions.ReadFunctionArgExprNode; 5 | import com.oracle.truffle.api.dsl.GenerateNodeFactory; 6 | import com.oracle.truffle.api.dsl.NodeChild; 7 | 8 | /** 9 | * The common ancestor for Nodes that represent the implementations of 10 | * built-in JavaScript functions. 11 | * Identical to the class with the same name from part 6. 12 | */ 13 | @NodeChild(value = "arguments", type = ReadFunctionArgExprNode[].class) 14 | @GenerateNodeFactory 15 | public abstract class BuiltInFunctionBodyExprNode extends EasyScriptExprNode { 16 | } 17 | -------------------------------------------------------------------------------- /part-08/src/main/java/com/endoflineblog/truffle/part_08/nodes/exprs/functions/built_in/BuiltInFunctionBodyExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_08.nodes.exprs.functions.built_in; 2 | 3 | import com.endoflineblog.truffle.part_08.nodes.exprs.EasyScriptExprNode; 4 | import com.endoflineblog.truffle.part_08.nodes.exprs.functions.ReadFunctionArgExprNode; 5 | import com.oracle.truffle.api.dsl.GenerateNodeFactory; 6 | import com.oracle.truffle.api.dsl.NodeChild; 7 | 8 | /** 9 | * The common ancestor for Nodes that represent the implementations of 10 | * built-in JavaScript functions. 11 | * Identical to the class with the same name from part 7. 12 | */ 13 | @NodeChild(value = "arguments", type = ReadFunctionArgExprNode[].class) 14 | @GenerateNodeFactory 15 | public abstract class BuiltInFunctionBodyExprNode extends EasyScriptExprNode { 16 | } 17 | -------------------------------------------------------------------------------- /part-09/src/main/java/com/endoflineblog/truffle/part_09/nodes/exprs/functions/built_in/BuiltInFunctionBodyExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_09.nodes.exprs.functions.built_in; 2 | 3 | import com.endoflineblog.truffle.part_09.nodes.exprs.EasyScriptExprNode; 4 | import com.endoflineblog.truffle.part_09.nodes.exprs.functions.ReadFunctionArgExprNode; 5 | import com.oracle.truffle.api.dsl.GenerateNodeFactory; 6 | import com.oracle.truffle.api.dsl.NodeChild; 7 | 8 | /** 9 | * The common ancestor for Nodes that represent the implementations of 10 | * built-in JavaScript functions. 11 | * Identical to the class with the same name from part 8. 12 | */ 13 | @NodeChild(value = "arguments", type = ReadFunctionArgExprNode[].class) 14 | @GenerateNodeFactory 15 | public abstract class BuiltInFunctionBodyExprNode extends EasyScriptExprNode { 16 | } 17 | -------------------------------------------------------------------------------- /part-10/src/main/java/com/endoflineblog/truffle/part_10/nodes/exprs/functions/built_in/BuiltInFunctionBodyExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_10.nodes.exprs.functions.built_in; 2 | 3 | import com.endoflineblog.truffle.part_10.nodes.exprs.EasyScriptExprNode; 4 | import com.endoflineblog.truffle.part_10.nodes.exprs.functions.ReadFunctionArgExprNode; 5 | import com.oracle.truffle.api.dsl.GenerateNodeFactory; 6 | import com.oracle.truffle.api.dsl.NodeChild; 7 | 8 | /** 9 | * The common ancestor for Nodes that represent the implementations of 10 | * built-in JavaScript functions. 11 | * Identical to the class with the same name from part 9. 12 | */ 13 | @NodeChild(value = "arguments", type = ReadFunctionArgExprNode[].class) 14 | @GenerateNodeFactory 15 | public abstract class BuiltInFunctionBodyExprNode extends EasyScriptExprNode { 16 | } 17 | -------------------------------------------------------------------------------- /part-11/src/main/java/com/endoflineblog/truffle/part_11/nodes/exprs/functions/built_in/BuiltInFunctionBodyExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_11.nodes.exprs.functions.built_in; 2 | 3 | import com.endoflineblog.truffle.part_11.nodes.exprs.EasyScriptExprNode; 4 | import com.endoflineblog.truffle.part_11.nodes.exprs.functions.ReadFunctionArgExprNode; 5 | import com.oracle.truffle.api.dsl.GenerateNodeFactory; 6 | import com.oracle.truffle.api.dsl.NodeChild; 7 | 8 | /** 9 | * The common ancestor for Nodes that represent the implementations of 10 | * built-in JavaScript functions and methods. 11 | * Identical to the class with the same name from part 10. 12 | */ 13 | @NodeChild(value = "arguments", type = ReadFunctionArgExprNode[].class) 14 | @GenerateNodeFactory 15 | public abstract class BuiltInFunctionBodyExprNode extends EasyScriptExprNode { 16 | } 17 | -------------------------------------------------------------------------------- /part-12/src/main/java/com/endoflineblog/truffle/part_12/nodes/exprs/functions/built_in/BuiltInFunctionBodyExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_12.nodes.exprs.functions.built_in; 2 | 3 | import com.endoflineblog.truffle.part_12.nodes.exprs.EasyScriptExprNode; 4 | import com.endoflineblog.truffle.part_12.nodes.exprs.functions.ReadFunctionArgExprNode; 5 | import com.oracle.truffle.api.dsl.GenerateNodeFactory; 6 | import com.oracle.truffle.api.dsl.NodeChild; 7 | 8 | /** 9 | * The common ancestor for Nodes that represent the implementations of 10 | * built-in JavaScript functions and methods. 11 | * Identical to the class with the same name from part 11. 12 | */ 13 | @NodeChild(value = "arguments", type = ReadFunctionArgExprNode[].class) 14 | @GenerateNodeFactory 15 | public abstract class BuiltInFunctionBodyExprNode extends EasyScriptExprNode { 16 | } 17 | -------------------------------------------------------------------------------- /part-13/src/main/java/com/endoflineblog/truffle/part_13/nodes/exprs/functions/built_in/BuiltInFunctionBodyExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_13.nodes.exprs.functions.built_in; 2 | 3 | import com.endoflineblog.truffle.part_13.nodes.exprs.EasyScriptExprNode; 4 | import com.endoflineblog.truffle.part_13.nodes.exprs.functions.ReadFunctionArgExprNode; 5 | import com.oracle.truffle.api.dsl.GenerateNodeFactory; 6 | import com.oracle.truffle.api.dsl.NodeChild; 7 | 8 | /** 9 | * The common ancestor for Nodes that represent the implementations of 10 | * built-in JavaScript functions and methods. 11 | * Identical to the class with the same name from part 12. 12 | */ 13 | @NodeChild(value = "arguments", type = ReadFunctionArgExprNode[].class) 14 | @GenerateNodeFactory 15 | public abstract class BuiltInFunctionBodyExprNode extends EasyScriptExprNode { 16 | } 17 | -------------------------------------------------------------------------------- /part-14/src/main/java/com/endoflineblog/truffle/part_14/nodes/exprs/functions/built_in/BuiltInFunctionBodyExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_14.nodes.exprs.functions.built_in; 2 | 3 | import com.endoflineblog.truffle.part_14.nodes.exprs.EasyScriptExprNode; 4 | import com.endoflineblog.truffle.part_14.nodes.exprs.functions.ReadFunctionArgExprNode; 5 | import com.oracle.truffle.api.dsl.GenerateNodeFactory; 6 | import com.oracle.truffle.api.dsl.NodeChild; 7 | 8 | /** 9 | * The common ancestor for Nodes that represent the implementations of 10 | * built-in JavaScript functions and methods. 11 | * Identical to the class with the same name from part 13. 12 | */ 13 | @NodeChild(value = "arguments", type = ReadFunctionArgExprNode[].class) 14 | @GenerateNodeFactory 15 | public abstract class BuiltInFunctionBodyExprNode extends EasyScriptExprNode { 16 | } 17 | -------------------------------------------------------------------------------- /part-15/src/main/java/com/endoflineblog/truffle/part_15/nodes/exprs/functions/built_in/BuiltInFunctionBodyExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_15.nodes.exprs.functions.built_in; 2 | 3 | import com.endoflineblog.truffle.part_15.nodes.exprs.EasyScriptExprNode; 4 | import com.endoflineblog.truffle.part_15.nodes.exprs.functions.ReadFunctionArgExprNode; 5 | import com.oracle.truffle.api.dsl.GenerateNodeFactory; 6 | import com.oracle.truffle.api.dsl.NodeChild; 7 | 8 | /** 9 | * The common ancestor for Nodes that represent the implementations of 10 | * built-in JavaScript functions and methods. 11 | * Identical to the class with the same name from part 14. 12 | */ 13 | @NodeChild(value = "arguments", type = ReadFunctionArgExprNode[].class) 14 | @GenerateNodeFactory 15 | public abstract class BuiltInFunctionBodyExprNode extends EasyScriptExprNode { 16 | } 17 | -------------------------------------------------------------------------------- /part-16/src/main/java/com/endoflineblog/truffle/part_16/nodes/exprs/functions/built_in/BuiltInFunctionBodyExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_16.nodes.exprs.functions.built_in; 2 | 3 | import com.endoflineblog.truffle.part_16.nodes.exprs.EasyScriptExprNode; 4 | import com.endoflineblog.truffle.part_16.nodes.exprs.functions.ReadFunctionArgExprNode; 5 | import com.oracle.truffle.api.dsl.GenerateNodeFactory; 6 | import com.oracle.truffle.api.dsl.NodeChild; 7 | 8 | /** 9 | * The common ancestor for Nodes that represent the implementations of 10 | * built-in JavaScript functions and methods. 11 | * Identical to the class with the same name from part 15. 12 | */ 13 | @NodeChild(value = "arguments", type = ReadFunctionArgExprNode[].class) 14 | @GenerateNodeFactory 15 | public abstract class BuiltInFunctionBodyExprNode extends EasyScriptExprNode { 16 | } 17 | -------------------------------------------------------------------------------- /part-01/src/main/java/com/endoflineblog/truffle/part_01/AdditionNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_01; 2 | 3 | import com.oracle.truffle.api.frame.VirtualFrame; 4 | 5 | /** 6 | * The AST node that represents the plus operator in EasyScript. 7 | */ 8 | public final class AdditionNode extends EasyScriptNode { 9 | @SuppressWarnings("FieldMayBeFinal") 10 | @Child 11 | private EasyScriptNode leftNode, rightNode; 12 | 13 | public AdditionNode(EasyScriptNode leftNode, EasyScriptNode rightNode) { 14 | this.leftNode = leftNode; 15 | this.rightNode = rightNode; 16 | } 17 | 18 | @Override 19 | public int executeInt(VirtualFrame frame) { 20 | int leftValue = this.leftNode.executeInt(frame); 21 | int rightValue = this.rightNode.executeInt(frame); 22 | return leftValue + rightValue; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /part-01/src/test/java/com/endoflineblog/truffle/part_01/ExecuteNodesTest.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_01; 2 | 3 | import com.oracle.truffle.api.CallTarget; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import static org.junit.jupiter.api.Assertions.assertEquals; 7 | 8 | class ExecuteNodesTest { 9 | /** 10 | * A simple test that interprets the expression '12 + 34', 11 | * and verifies it evaluates to 46. 12 | */ 13 | @Test 14 | void adds_12_and_34_correctly() { 15 | EasyScriptNode exprNode = new AdditionNode( 16 | new IntLiteralNode(12), 17 | new IntLiteralNode(34)); 18 | var rootNode = new EasyScriptRootNode(exprNode); 19 | CallTarget callTarget = rootNode.getCallTarget(); 20 | 21 | Object result = callTarget.call(); 22 | 23 | assertEquals(46, result); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /part-05/src/main/java/com/endoflineblog/truffle/part_05/DeclarationKind.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_05; 2 | 3 | /** 4 | * An enum that represents the different kinds of variable declarations in JavaScript. 5 | */ 6 | public enum DeclarationKind { 7 | /** This represents the 'var' declaration kind. */ 8 | VAR, 9 | 10 | /** This represents the 'let' declaration kind. */ 11 | LET, 12 | 13 | /** This represents the 'const' declaration kind. */ 14 | CONST; 15 | 16 | public static DeclarationKind fromToken(String token) { 17 | switch (token) { 18 | case "var": return DeclarationKind.VAR; 19 | case "let": return DeclarationKind.LET; 20 | case "const": return DeclarationKind.CONST; 21 | default: throw new EasyScriptException("Unrecognized variable kind: '" + token + "'"); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /part-05/src/main/java/com/endoflineblog/truffle/part_05/nodes/exprs/IntLiteralExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_05.nodes.exprs; 2 | 3 | import com.oracle.truffle.api.frame.VirtualFrame; 4 | 5 | /** 6 | * The AST node that represents an integer literal expression in EasyScript. 7 | * Same as IntLiteralNode from part 3. 8 | */ 9 | public final class IntLiteralExprNode extends EasyScriptExprNode { 10 | private final int value; 11 | 12 | public IntLiteralExprNode(int value) { 13 | this.value = value; 14 | } 15 | 16 | @Override 17 | public int executeInt(VirtualFrame frame) { 18 | return this.value; 19 | } 20 | 21 | @Override 22 | public double executeDouble(VirtualFrame frame) { 23 | return this.value; 24 | } 25 | 26 | @Override 27 | public Object executeGeneric(VirtualFrame frame) { 28 | return this.value; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /part-03/src/main/java/com/endoflineblog/truffle/part_03/IntLiteralNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_03; 2 | 3 | import com.oracle.truffle.api.frame.VirtualFrame; 4 | 5 | /** 6 | * The AST node that represents an integer literal expression in EasyScript. 7 | * Pretty much identical to {@link com.endoflineblog.truffle.part_02.IntLiteralNode}. 8 | */ 9 | public final class IntLiteralNode extends EasyScriptNode { 10 | private final int value; 11 | 12 | public IntLiteralNode(int value) { 13 | this.value = value; 14 | } 15 | 16 | @Override 17 | public int executeInt(VirtualFrame frame) { 18 | return this.value; 19 | } 20 | 21 | @Override 22 | public double executeDouble(VirtualFrame frame) { 23 | return this.value; 24 | } 25 | 26 | @Override 27 | public Object executeGeneric(VirtualFrame frame) { 28 | return this.value; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /part-01/src/test/java/com/endoflineblog/truffle/part_01/OverflowTest.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_01; 2 | 3 | import com.oracle.truffle.api.CallTarget; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import static org.junit.jupiter.api.Assertions.assertEquals; 7 | 8 | /** 9 | * A test illustrating that the simple addition implementation does not handle overflow correctly. 10 | * It will be fixed in part 2. 11 | */ 12 | class OverflowTest { 13 | @Test 14 | void adding_1_to_int_max_overflows() { 15 | EasyScriptNode exprNode = new AdditionNode( 16 | new IntLiteralNode(Integer.MAX_VALUE), 17 | new IntLiteralNode(1)); 18 | var rootNode = new EasyScriptRootNode(exprNode); 19 | CallTarget callTarget = rootNode.getCallTarget(); 20 | 21 | Object result = callTarget.call(); 22 | 23 | assertEquals(Integer.MIN_VALUE, result); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /part-06/src/main/java/com/endoflineblog/truffle/part_06/nodes/exprs/IntLiteralExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_06.nodes.exprs; 2 | 3 | import com.oracle.truffle.api.frame.VirtualFrame; 4 | 5 | /** 6 | * The AST node that represents an integer literal expression in EasyScript. 7 | * Identical to the class with the same name from part 5. 8 | */ 9 | public final class IntLiteralExprNode extends EasyScriptExprNode { 10 | private final int value; 11 | 12 | public IntLiteralExprNode(int value) { 13 | this.value = value; 14 | } 15 | 16 | @Override 17 | public int executeInt(VirtualFrame frame) { 18 | return this.value; 19 | } 20 | 21 | @Override 22 | public double executeDouble(VirtualFrame frame) { 23 | return this.value; 24 | } 25 | 26 | @Override 27 | public Object executeGeneric(VirtualFrame frame) { 28 | return this.value; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /part-07/src/main/java/com/endoflineblog/truffle/part_07/nodes/exprs/IntLiteralExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_07.nodes.exprs; 2 | 3 | import com.oracle.truffle.api.frame.VirtualFrame; 4 | 5 | /** 6 | * The AST node that represents an integer literal expression in EasyScript. 7 | * Identical to the class with the same name from part 6. 8 | */ 9 | public final class IntLiteralExprNode extends EasyScriptExprNode { 10 | private final int value; 11 | 12 | public IntLiteralExprNode(int value) { 13 | this.value = value; 14 | } 15 | 16 | @Override 17 | public int executeInt(VirtualFrame frame) { 18 | return this.value; 19 | } 20 | 21 | @Override 22 | public double executeDouble(VirtualFrame frame) { 23 | return this.value; 24 | } 25 | 26 | @Override 27 | public Object executeGeneric(VirtualFrame frame) { 28 | return this.value; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /part-06/src/main/java/com/endoflineblog/truffle/part_06/DeclarationKind.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_06; 2 | 3 | /** 4 | * An enum that represents the different kinds of variable declarations in JavaScript. 5 | * Identical to the enum with the same name from part 5. 6 | */ 7 | public enum DeclarationKind { 8 | /** This represents the 'var' declaration kind. */ 9 | VAR, 10 | 11 | /** This represents the 'let' declaration kind. */ 12 | LET, 13 | 14 | /** This represents the 'const' declaration kind. */ 15 | CONST; 16 | 17 | public static DeclarationKind fromToken(String token) { 18 | switch (token) { 19 | case "var": return DeclarationKind.VAR; 20 | case "let": return DeclarationKind.LET; 21 | case "const": return DeclarationKind.CONST; 22 | default: throw new EasyScriptException("Unrecognized variable kind: '" + token + "'"); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /part-07/src/main/java/com/endoflineblog/truffle/part_07/DeclarationKind.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_07; 2 | 3 | /** 4 | * An enum that represents the different kinds of variable declarations in JavaScript. 5 | * Identical to the enum with the same name from part 6. 6 | */ 7 | public enum DeclarationKind { 8 | /** This represents the 'var' declaration kind. */ 9 | VAR, 10 | 11 | /** This represents the 'let' declaration kind. */ 12 | LET, 13 | 14 | /** This represents the 'const' declaration kind. */ 15 | CONST; 16 | 17 | public static DeclarationKind fromToken(String token) { 18 | switch (token) { 19 | case "var": return DeclarationKind.VAR; 20 | case "let": return DeclarationKind.LET; 21 | case "const": return DeclarationKind.CONST; 22 | default: throw new EasyScriptException("Unrecognized variable kind: '" + token + "'"); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /part-03/src/main/java/com/endoflineblog/truffle/part_03/EasyScriptRootNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_03; 2 | 3 | import com.oracle.truffle.api.frame.VirtualFrame; 4 | import com.oracle.truffle.api.nodes.RootNode; 5 | 6 | /** 7 | * A Truffle AST must be anchored in a {@link RootNode} 8 | * to be executed. 9 | * Since {@link RootNode} is an abstract class, 10 | * you're expected to subclass it, 11 | * and override the abstract {@link #execute} method. 12 | * 13 | * @see #execute 14 | */ 15 | public final class EasyScriptRootNode extends RootNode { 16 | @SuppressWarnings("FieldMayBeFinal") 17 | @Child 18 | private EasyScriptNode exprNode; 19 | 20 | public EasyScriptRootNode(EasyScriptNode exprNode) { 21 | super(null); 22 | 23 | this.exprNode = exprNode; 24 | } 25 | 26 | @Override 27 | public Object execute(VirtualFrame frame) { 28 | return this.exprNode.executeGeneric(frame); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /part-05/src/main/java/com/endoflineblog/truffle/part_05/nodes/stmts/ExprStmtNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_05.nodes.stmts; 2 | 3 | import com.endoflineblog.truffle.part_05.nodes.exprs.EasyScriptExprNode; 4 | import com.oracle.truffle.api.frame.VirtualFrame; 5 | 6 | /** A Node that represents an expression statement. */ 7 | public final class ExprStmtNode extends EasyScriptStmtNode { 8 | @SuppressWarnings("FieldMayBeFinal") 9 | @Child 10 | private EasyScriptExprNode expr; 11 | 12 | /** 13 | * Creates a new instance of the expression statement. 14 | * 15 | * @param expr the expression node 16 | */ 17 | public ExprStmtNode(EasyScriptExprNode expr) { 18 | this.expr = expr; 19 | } 20 | 21 | /** Evaluating the statement returns the result of executing its expression. */ 22 | @Override 23 | public Object executeStatement(VirtualFrame frame) { 24 | return this.expr.executeGeneric(frame); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /part-08/src/main/java/com/endoflineblog/truffle/part_08/nodes/exprs/comparisons/LesserExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_08.nodes.exprs.comparisons; 2 | 3 | import com.endoflineblog.truffle.part_08.nodes.exprs.BinaryOperationExprNode; 4 | import com.oracle.truffle.api.dsl.Fallback; 5 | import com.oracle.truffle.api.dsl.Specialization; 6 | 7 | /** 8 | * Node class representing the lesser ({@code <}) operator. 9 | */ 10 | public abstract class LesserExprNode extends BinaryOperationExprNode { 11 | @Specialization 12 | protected boolean intLesser(int leftValue, int rightValue) { 13 | return leftValue < rightValue; 14 | } 15 | 16 | @Specialization(replaces = "intLesser") 17 | protected boolean doubleLesser(double leftValue, double rightValue) { 18 | return leftValue < rightValue; 19 | } 20 | 21 | @Fallback 22 | protected boolean objectLesser(Object leftValue, Object rightValue) { 23 | return false; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /part-08/src/main/java/com/endoflineblog/truffle/part_08/nodes/exprs/comparisons/GreaterExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_08.nodes.exprs.comparisons; 2 | 3 | import com.endoflineblog.truffle.part_08.nodes.exprs.BinaryOperationExprNode; 4 | import com.oracle.truffle.api.dsl.Fallback; 5 | import com.oracle.truffle.api.dsl.Specialization; 6 | 7 | /** 8 | * Node class representing the greater ({@code >}) operator. 9 | */ 10 | public abstract class GreaterExprNode extends BinaryOperationExprNode { 11 | @Specialization 12 | protected boolean intGreater(int leftValue, int rightValue) { 13 | return leftValue > rightValue; 14 | } 15 | 16 | @Specialization(replaces = "intGreater") 17 | protected boolean doubleGreater(double leftValue, double rightValue) { 18 | return leftValue > rightValue; 19 | } 20 | 21 | @Fallback 22 | protected boolean objectGreater(Object leftValue, Object rightValue) { 23 | return false; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /part-08/src/main/java/com/endoflineblog/truffle/part_08/nodes/EasyScriptNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_08.nodes; 2 | 3 | import com.endoflineblog.truffle.part_08.EasyScriptLanguageContext; 4 | import com.endoflineblog.truffle.part_08.EasyScriptTruffleLanguage; 5 | import com.oracle.truffle.api.nodes.Node; 6 | 7 | /** 8 | * The abstract common ancestor of all EasyScript AST Truffle Nodes. 9 | * Identical to the class with the same name from part 7. 10 | */ 11 | public abstract class EasyScriptNode extends Node { 12 | /** Allows retrieving the current Truffle language instance from within a Node. */ 13 | protected final EasyScriptTruffleLanguage currentTruffleLanguage() { 14 | return EasyScriptTruffleLanguage.get(this); 15 | } 16 | 17 | /** Allows retrieving the current Truffle language Context from within a Node. */ 18 | protected final EasyScriptLanguageContext currentLanguageContext() { 19 | return EasyScriptLanguageContext.get(this); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /part-08/src/main/java/com/endoflineblog/truffle/part_08/nodes/exprs/functions/ReadFunctionArgExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_08.nodes.exprs.functions; 2 | 3 | import com.endoflineblog.truffle.part_08.nodes.exprs.EasyScriptExprNode; 4 | import com.oracle.truffle.api.frame.VirtualFrame; 5 | 6 | /** 7 | * An expression Node that represents referencing a given argument of a function - 8 | * either built-in, or user-defined. 9 | * Identical to the class with the same name from part 7. 10 | */ 11 | public final class ReadFunctionArgExprNode extends EasyScriptExprNode { 12 | private final int index; 13 | 14 | public ReadFunctionArgExprNode(int index) { 15 | this.index = index; 16 | } 17 | 18 | @Override 19 | public Object executeGeneric(VirtualFrame frame) { 20 | // we are guaranteed the argument array has enough elements, 21 | // because of the logic in FunctionDispatchNode 22 | return frame.getArguments()[this.index]; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /part-09/src/main/java/com/endoflineblog/truffle/part_09/nodes/EasyScriptNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_09.nodes; 2 | 3 | import com.endoflineblog.truffle.part_09.EasyScriptLanguageContext; 4 | import com.endoflineblog.truffle.part_09.EasyScriptTruffleLanguage; 5 | import com.oracle.truffle.api.nodes.Node; 6 | 7 | /** 8 | * The abstract common ancestor of all EasyScript AST Truffle Nodes. 9 | * Identical to the class with the same name from part 8. 10 | */ 11 | public abstract class EasyScriptNode extends Node { 12 | /** Allows retrieving the current Truffle language instance from within a Node. */ 13 | protected final EasyScriptTruffleLanguage currentTruffleLanguage() { 14 | return EasyScriptTruffleLanguage.get(this); 15 | } 16 | 17 | /** Allows retrieving the current Truffle language Context from within a Node. */ 18 | protected final EasyScriptLanguageContext currentLanguageContext() { 19 | return EasyScriptLanguageContext.get(this); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /part-09/src/main/java/com/endoflineblog/truffle/part_09/nodes/exprs/functions/ReadFunctionArgExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_09.nodes.exprs.functions; 2 | 3 | import com.endoflineblog.truffle.part_09.nodes.exprs.EasyScriptExprNode; 4 | import com.oracle.truffle.api.frame.VirtualFrame; 5 | 6 | /** 7 | * An expression Node that represents referencing a given argument of a function - 8 | * either built-in, or user-defined. 9 | * Identical to the class with the same name from part 8. 10 | */ 11 | public final class ReadFunctionArgExprNode extends EasyScriptExprNode { 12 | private final int index; 13 | 14 | public ReadFunctionArgExprNode(int index) { 15 | this.index = index; 16 | } 17 | 18 | @Override 19 | public Object executeGeneric(VirtualFrame frame) { 20 | // we are guaranteed the argument array has enough elements, 21 | // because of the logic in FunctionDispatchNode 22 | return frame.getArguments()[this.index]; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /part-10/src/main/java/com/endoflineblog/truffle/part_10/nodes/EasyScriptNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_10.nodes; 2 | 3 | import com.endoflineblog.truffle.part_10.EasyScriptLanguageContext; 4 | import com.endoflineblog.truffle.part_10.EasyScriptTruffleLanguage; 5 | import com.oracle.truffle.api.nodes.Node; 6 | 7 | /** 8 | * The abstract common ancestor of all EasyScript AST Truffle Nodes. 9 | * Identical to the class with the same name from part 9. 10 | */ 11 | public abstract class EasyScriptNode extends Node { 12 | /** Allows retrieving the current Truffle language instance from within a Node. */ 13 | protected final EasyScriptTruffleLanguage currentTruffleLanguage() { 14 | return EasyScriptTruffleLanguage.get(this); 15 | } 16 | 17 | /** Allows retrieving the current Truffle language Context from within a Node. */ 18 | protected final EasyScriptLanguageContext currentLanguageContext() { 19 | return EasyScriptLanguageContext.get(this); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /part-10/src/main/java/com/endoflineblog/truffle/part_10/nodes/exprs/functions/ReadFunctionArgExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_10.nodes.exprs.functions; 2 | 3 | import com.endoflineblog.truffle.part_10.nodes.exprs.EasyScriptExprNode; 4 | import com.oracle.truffle.api.frame.VirtualFrame; 5 | 6 | /** 7 | * An expression Node that represents referencing a given argument of a function - 8 | * either built-in, or user-defined. 9 | * Identical to the class with the same name from part 9. 10 | */ 11 | public final class ReadFunctionArgExprNode extends EasyScriptExprNode { 12 | private final int index; 13 | 14 | public ReadFunctionArgExprNode(int index) { 15 | this.index = index; 16 | } 17 | 18 | @Override 19 | public Object executeGeneric(VirtualFrame frame) { 20 | // we are guaranteed the argument array has enough elements, 21 | // because of the logic in FunctionDispatchNode 22 | return frame.getArguments()[this.index]; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /part-11/src/main/java/com/endoflineblog/truffle/part_11/nodes/EasyScriptNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_11.nodes; 2 | 3 | import com.endoflineblog.truffle.part_11.EasyScriptLanguageContext; 4 | import com.endoflineblog.truffle.part_11.EasyScriptTruffleLanguage; 5 | import com.oracle.truffle.api.nodes.Node; 6 | 7 | /** 8 | * The abstract common ancestor of all EasyScript AST Truffle Nodes. 9 | * Identical to the class with the same name from part 10. 10 | */ 11 | public abstract class EasyScriptNode extends Node { 12 | /** Allows retrieving the current Truffle language instance from within a Node. */ 13 | protected final EasyScriptTruffleLanguage currentTruffleLanguage() { 14 | return EasyScriptTruffleLanguage.get(this); 15 | } 16 | 17 | /** Allows retrieving the current Truffle language Context from within a Node. */ 18 | protected final EasyScriptLanguageContext currentLanguageContext() { 19 | return EasyScriptLanguageContext.get(this); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /part-11/src/main/java/com/endoflineblog/truffle/part_11/nodes/exprs/functions/ReadFunctionArgExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_11.nodes.exprs.functions; 2 | 3 | import com.endoflineblog.truffle.part_11.nodes.exprs.EasyScriptExprNode; 4 | import com.oracle.truffle.api.frame.VirtualFrame; 5 | 6 | /** 7 | * An expression Node that represents referencing a given argument of a function - 8 | * either built-in, or user-defined. 9 | * Identical to the class with the same name from part 10. 10 | */ 11 | public final class ReadFunctionArgExprNode extends EasyScriptExprNode { 12 | private final int index; 13 | 14 | public ReadFunctionArgExprNode(int index) { 15 | this.index = index; 16 | } 17 | 18 | @Override 19 | public Object executeGeneric(VirtualFrame frame) { 20 | // we are guaranteed the argument array has enough elements, 21 | // because of the logic in FunctionDispatchNode 22 | return frame.getArguments()[this.index]; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /part-12/src/main/java/com/endoflineblog/truffle/part_12/nodes/EasyScriptNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_12.nodes; 2 | 3 | import com.endoflineblog.truffle.part_12.EasyScriptLanguageContext; 4 | import com.endoflineblog.truffle.part_12.EasyScriptTruffleLanguage; 5 | import com.oracle.truffle.api.nodes.Node; 6 | 7 | /** 8 | * The abstract common ancestor of all EasyScript AST Truffle Nodes. 9 | * Identical to the class with the same name from part 11. 10 | */ 11 | public abstract class EasyScriptNode extends Node { 12 | /** Allows retrieving the current Truffle language instance from within a Node. */ 13 | protected final EasyScriptTruffleLanguage currentTruffleLanguage() { 14 | return EasyScriptTruffleLanguage.get(this); 15 | } 16 | 17 | /** Allows retrieving the current Truffle language Context from within a Node. */ 18 | protected final EasyScriptLanguageContext currentLanguageContext() { 19 | return EasyScriptLanguageContext.get(this); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /part-12/src/main/java/com/endoflineblog/truffle/part_12/nodes/exprs/functions/ReadFunctionArgExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_12.nodes.exprs.functions; 2 | 3 | import com.endoflineblog.truffle.part_12.nodes.exprs.EasyScriptExprNode; 4 | import com.oracle.truffle.api.frame.VirtualFrame; 5 | 6 | /** 7 | * An expression Node that represents referencing a given argument of a function - 8 | * either built-in, or user-defined. 9 | * Identical to the class with the same name from part 11. 10 | */ 11 | public final class ReadFunctionArgExprNode extends EasyScriptExprNode { 12 | private final int index; 13 | 14 | public ReadFunctionArgExprNode(int index) { 15 | this.index = index; 16 | } 17 | 18 | @Override 19 | public Object executeGeneric(VirtualFrame frame) { 20 | // we are guaranteed the argument array has enough elements, 21 | // because of the logic in FunctionDispatchNode 22 | return frame.getArguments()[this.index]; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /part-13/src/main/java/com/endoflineblog/truffle/part_13/nodes/EasyScriptNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_13.nodes; 2 | 3 | import com.endoflineblog.truffle.part_13.EasyScriptLanguageContext; 4 | import com.endoflineblog.truffle.part_13.EasyScriptTruffleLanguage; 5 | import com.oracle.truffle.api.nodes.Node; 6 | 7 | /** 8 | * The abstract common ancestor of all EasyScript AST Truffle Nodes. 9 | * Identical to the class with the same name from part 12. 10 | */ 11 | public abstract class EasyScriptNode extends Node { 12 | /** Allows retrieving the current Truffle language instance from within a Node. */ 13 | protected final EasyScriptTruffleLanguage currentTruffleLanguage() { 14 | return EasyScriptTruffleLanguage.get(this); 15 | } 16 | 17 | /** Allows retrieving the current Truffle language Context from within a Node. */ 18 | protected final EasyScriptLanguageContext currentLanguageContext() { 19 | return EasyScriptLanguageContext.get(this); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /part-13/src/main/java/com/endoflineblog/truffle/part_13/nodes/exprs/functions/ReadFunctionArgExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_13.nodes.exprs.functions; 2 | 3 | import com.endoflineblog.truffle.part_13.nodes.exprs.EasyScriptExprNode; 4 | import com.oracle.truffle.api.frame.VirtualFrame; 5 | 6 | /** 7 | * An expression Node that represents referencing a given argument of a function - 8 | * either built-in, or user-defined. 9 | * Identical to the class with the same name from part 12. 10 | */ 11 | public final class ReadFunctionArgExprNode extends EasyScriptExprNode { 12 | private final int index; 13 | 14 | public ReadFunctionArgExprNode(int index) { 15 | this.index = index; 16 | } 17 | 18 | @Override 19 | public Object executeGeneric(VirtualFrame frame) { 20 | // we are guaranteed the argument array has enough elements, 21 | // because of the logic in FunctionDispatchNode 22 | return frame.getArguments()[this.index]; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /part-14/src/main/java/com/endoflineblog/truffle/part_14/nodes/EasyScriptNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_14.nodes; 2 | 3 | import com.endoflineblog.truffle.part_14.EasyScriptLanguageContext; 4 | import com.endoflineblog.truffle.part_14.EasyScriptTruffleLanguage; 5 | import com.oracle.truffle.api.nodes.Node; 6 | 7 | /** 8 | * The abstract common ancestor of all EasyScript AST Truffle Nodes. 9 | * Identical to the class with the same name from part 13. 10 | */ 11 | public abstract class EasyScriptNode extends Node { 12 | /** Allows retrieving the current Truffle language instance from within a Node. */ 13 | protected final EasyScriptTruffleLanguage currentTruffleLanguage() { 14 | return EasyScriptTruffleLanguage.get(this); 15 | } 16 | 17 | /** Allows retrieving the current Truffle language Context from within a Node. */ 18 | protected final EasyScriptLanguageContext currentLanguageContext() { 19 | return EasyScriptLanguageContext.get(this); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /part-14/src/main/java/com/endoflineblog/truffle/part_14/nodes/exprs/functions/ReadFunctionArgExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_14.nodes.exprs.functions; 2 | 3 | import com.endoflineblog.truffle.part_14.nodes.exprs.EasyScriptExprNode; 4 | import com.oracle.truffle.api.frame.VirtualFrame; 5 | 6 | /** 7 | * An expression Node that represents referencing a given argument of a function - 8 | * either built-in, or user-defined. 9 | * Identical to the class with the same name from part 13. 10 | */ 11 | public final class ReadFunctionArgExprNode extends EasyScriptExprNode { 12 | private final int index; 13 | 14 | public ReadFunctionArgExprNode(int index) { 15 | this.index = index; 16 | } 17 | 18 | @Override 19 | public Object executeGeneric(VirtualFrame frame) { 20 | // we are guaranteed the argument array has enough elements, 21 | // because of the logic in FunctionDispatchNode 22 | return frame.getArguments()[this.index]; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /part-15/src/main/java/com/endoflineblog/truffle/part_15/nodes/EasyScriptNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_15.nodes; 2 | 3 | import com.endoflineblog.truffle.part_15.EasyScriptLanguageContext; 4 | import com.endoflineblog.truffle.part_15.EasyScriptTruffleLanguage; 5 | import com.oracle.truffle.api.nodes.Node; 6 | 7 | /** 8 | * The abstract common ancestor of all EasyScript AST Truffle Nodes. 9 | * Identical to the class with the same name from part 14. 10 | */ 11 | public abstract class EasyScriptNode extends Node { 12 | /** Allows retrieving the current Truffle language instance from within a Node. */ 13 | protected final EasyScriptTruffleLanguage currentTruffleLanguage() { 14 | return EasyScriptTruffleLanguage.get(this); 15 | } 16 | 17 | /** Allows retrieving the current Truffle language Context from within a Node. */ 18 | protected final EasyScriptLanguageContext currentLanguageContext() { 19 | return EasyScriptLanguageContext.get(this); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /part-15/src/main/java/com/endoflineblog/truffle/part_15/nodes/exprs/functions/ReadFunctionArgExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_15.nodes.exprs.functions; 2 | 3 | import com.endoflineblog.truffle.part_15.nodes.exprs.EasyScriptExprNode; 4 | import com.oracle.truffle.api.frame.VirtualFrame; 5 | 6 | /** 7 | * An expression Node that represents referencing a given argument of a function - 8 | * either built-in, or user-defined. 9 | * Identical to the class with the same name from part 14. 10 | */ 11 | public final class ReadFunctionArgExprNode extends EasyScriptExprNode { 12 | private final int index; 13 | 14 | public ReadFunctionArgExprNode(int index) { 15 | this.index = index; 16 | } 17 | 18 | @Override 19 | public Object executeGeneric(VirtualFrame frame) { 20 | // we are guaranteed the argument array has enough elements, 21 | // because of the logic in FunctionDispatchNode 22 | return frame.getArguments()[this.index]; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /part-16/src/main/java/com/endoflineblog/truffle/part_16/nodes/EasyScriptNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_16.nodes; 2 | 3 | import com.endoflineblog.truffle.part_16.EasyScriptLanguageContext; 4 | import com.endoflineblog.truffle.part_16.EasyScriptTruffleLanguage; 5 | import com.oracle.truffle.api.nodes.Node; 6 | 7 | /** 8 | * The abstract common ancestor of all EasyScript AST Truffle Nodes. 9 | * Identical to the class with the same name from part 15. 10 | */ 11 | public abstract class EasyScriptNode extends Node { 12 | /** Allows retrieving the current Truffle language instance from within a Node. */ 13 | protected final EasyScriptTruffleLanguage currentTruffleLanguage() { 14 | return EasyScriptTruffleLanguage.get(this); 15 | } 16 | 17 | /** Allows retrieving the current Truffle language Context from within a Node. */ 18 | protected final EasyScriptLanguageContext currentLanguageContext() { 19 | return EasyScriptLanguageContext.get(this); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /part-05/src/main/java/com/endoflineblog/truffle/part_05/nodes/exprs/GlobalVarReferenceExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_05.nodes.exprs; 2 | 3 | import com.endoflineblog.truffle.part_05.EasyScriptException; 4 | import com.oracle.truffle.api.dsl.NodeField; 5 | import com.oracle.truffle.api.dsl.Specialization; 6 | 7 | /** 8 | * A Node that represents the expression of referencing a global variable in EasyScript. 9 | */ 10 | @NodeField(name = "name", type = String.class) 11 | public abstract class GlobalVarReferenceExprNode extends EasyScriptExprNode { 12 | protected abstract String getName(); 13 | 14 | @Specialization 15 | protected Object readVariable() { 16 | String variableId = this.getName(); 17 | var value = this.currentLanguageContext().globalScopeObject.getVariable(variableId); 18 | if (value == null) { 19 | throw new EasyScriptException(this, "'" + variableId + "' is not defined"); 20 | } 21 | return value; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /part-04/src/test/java/com/endoflineblog/truffle/part_04/PolyglotTest.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_04; 2 | 3 | import org.graalvm.polyglot.Context; 4 | import org.graalvm.polyglot.Value; 5 | import org.junit.jupiter.api.AfterEach; 6 | import org.junit.jupiter.api.BeforeEach; 7 | import org.junit.jupiter.api.Test; 8 | 9 | import static org.junit.jupiter.api.Assertions.assertEquals; 10 | 11 | class PolyglotTest { 12 | private Context context; 13 | 14 | @BeforeEach 15 | void setUp() { 16 | this.context = Context.create(); 17 | } 18 | 19 | @AfterEach 20 | void tearDown() { 21 | this.context.close(); 22 | } 23 | 24 | /** 25 | * This test invokes the {@link EasyScriptTruffleLanguage} class 26 | * through GraalVM's polyglot API. 27 | */ 28 | @Test 29 | void runs_EasyScript_code() { 30 | Value result = this.context.eval("ezs", 31 | "10 + 24 + 56.0"); 32 | assertEquals(90.0, result.asDouble()); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /part-02/src/main/java/com/endoflineblog/truffle/part_02/EasyScriptRootNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_02; 2 | 3 | import com.oracle.truffle.api.frame.VirtualFrame; 4 | import com.oracle.truffle.api.nodes.RootNode; 5 | import com.oracle.truffle.api.nodes.UnexpectedResultException; 6 | 7 | /** 8 | * A Truffle AST must be anchored in a {@link RootNode} 9 | * to be executed. 10 | * Since {@link RootNode} is an abstract class, 11 | * you're expected to subclass it, 12 | * and override the abstract {@link #execute} method. 13 | * 14 | * @see #execute 15 | */ 16 | public final class EasyScriptRootNode extends RootNode { 17 | @SuppressWarnings("FieldMayBeFinal") 18 | @Child 19 | private EasyScriptNode exprNode; 20 | 21 | public EasyScriptRootNode(EasyScriptNode exprNode) { 22 | super(null); 23 | 24 | this.exprNode = exprNode; 25 | } 26 | 27 | @Override 28 | public Object execute(VirtualFrame frame) { 29 | return this.exprNode.executeGeneric(frame); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /part-05/src/main/java/com/endoflineblog/truffle/part_05/nodes/exprs/UndefinedLiteralExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_05.nodes.exprs; 2 | 3 | import com.endoflineblog.truffle.part_05.runtime.Undefined; 4 | import com.oracle.truffle.api.frame.VirtualFrame; 5 | import com.oracle.truffle.api.nodes.UnexpectedResultException; 6 | 7 | /** 8 | * The AST node that represents the 'undefined' literal JavaScript expression. 9 | */ 10 | public final class UndefinedLiteralExprNode extends EasyScriptExprNode { 11 | @Override 12 | public int executeInt(VirtualFrame frame) throws UnexpectedResultException { 13 | throw new UnexpectedResultException(Undefined.INSTANCE); 14 | } 15 | 16 | @Override 17 | public double executeDouble(VirtualFrame frame) throws UnexpectedResultException { 18 | throw new UnexpectedResultException(Undefined.INSTANCE); 19 | } 20 | 21 | @Override 22 | public Object executeGeneric(VirtualFrame frame) { 23 | return Undefined.INSTANCE; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /part-08/src/main/java/com/endoflineblog/truffle/part_08/nodes/stmts/controlflow/ReturnStmtNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_08.nodes.stmts.controlflow; 2 | 3 | import com.endoflineblog.truffle.part_08.exceptions.ReturnException; 4 | import com.endoflineblog.truffle.part_08.nodes.exprs.EasyScriptExprNode; 5 | import com.endoflineblog.truffle.part_08.nodes.stmts.EasyScriptStmtNode; 6 | import com.oracle.truffle.api.frame.VirtualFrame; 7 | 8 | /** A Node representing the {@code return} statement. */ 9 | public final class ReturnStmtNode extends EasyScriptStmtNode { 10 | @SuppressWarnings("FieldMayBeFinal") 11 | @Child 12 | private EasyScriptExprNode returnExpr; 13 | 14 | public ReturnStmtNode(EasyScriptExprNode returnExpr) { 15 | this.returnExpr = returnExpr; 16 | } 17 | 18 | @Override 19 | public Object executeStatement(VirtualFrame frame) { 20 | Object returnValue = this.returnExpr.executeGeneric(frame); 21 | throw new ReturnException(returnValue); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /part-08/src/main/java/com/endoflineblog/truffle/part_08/nodes/exprs/comparisons/LesserOrEqualExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_08.nodes.exprs.comparisons; 2 | 3 | import com.endoflineblog.truffle.part_08.nodes.exprs.BinaryOperationExprNode; 4 | import com.oracle.truffle.api.dsl.Fallback; 5 | import com.oracle.truffle.api.dsl.Specialization; 6 | 7 | /** 8 | * Node class representing the lesser or equal ({@code <=}) operator. 9 | */ 10 | public abstract class LesserOrEqualExprNode extends BinaryOperationExprNode { 11 | @Specialization 12 | protected boolean intLesserOrEqual(int leftValue, int rightValue) { 13 | return leftValue <= rightValue; 14 | } 15 | 16 | @Specialization(replaces = "intLesserOrEqual") 17 | protected boolean doubleLesserOrEqual(double leftValue, double rightValue) { 18 | return leftValue <= rightValue; 19 | } 20 | 21 | @Fallback 22 | protected boolean objectLesserOrEqual(Object leftValue, Object rightValue) { 23 | return false; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /part-16/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'antlr' 3 | id 'me.champeau.jmh' version '0.6.6' 4 | id 'application' 5 | } 6 | 7 | dependencies { 8 | antlr "org.antlr:antlr4:$antlr_version" 9 | implementation "org.graalvm.js:js:$graal_version" 10 | implementation "org.graalvm.tools:profiler:$graal_version" 11 | implementation "org.graalvm.tools:chromeinspector:$graal_version" 12 | implementation "org.apache.commons:commons-text:1.14.0" 13 | 14 | testImplementation "org.graalvm.truffle:truffle-tck:$graal_version" 15 | } 16 | 17 | // required to allow GraalVM to discover our EasyScript language class 18 | test { 19 | jvmArgs '-Dgraalvm.locatorDisabled=true' 20 | } 21 | 22 | String jmhIncludes = findProperty("jmhIncludes") 23 | jmh { 24 | if (jmhIncludes != null) { 25 | includes = [jmhIncludes] 26 | } 27 | } 28 | 29 | application { 30 | mainClass = 'com.endoflineblog.truffle.part_16.Main' 31 | applicationDefaultJvmArgs = [ 32 | '-Dgraalvm.locatorDisabled=true', 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /part-08/src/main/java/com/endoflineblog/truffle/part_08/nodes/exprs/comparisons/GreaterOrEqualExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_08.nodes.exprs.comparisons; 2 | 3 | import com.endoflineblog.truffle.part_08.nodes.exprs.BinaryOperationExprNode; 4 | import com.oracle.truffle.api.dsl.Fallback; 5 | import com.oracle.truffle.api.dsl.Specialization; 6 | 7 | /** 8 | * Node class representing the greater or equal ({@code >=}) operator. 9 | */ 10 | public abstract class GreaterOrEqualExprNode extends BinaryOperationExprNode { 11 | @Specialization 12 | protected boolean intGreaterOrEqual(int leftValue, int rightValue) { 13 | return leftValue >= rightValue; 14 | } 15 | 16 | @Specialization(replaces = "intGreaterOrEqual") 17 | protected boolean doubleGreaterOrEqual(double leftValue, double rightValue) { 18 | return leftValue >= rightValue; 19 | } 20 | 21 | @Fallback 22 | protected boolean objectGreaterOrEqual(Object leftValue, Object rightValue) { 23 | return false; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /part-09/src/main/java/com/endoflineblog/truffle/part_09/nodes/exprs/comparisons/LesserExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_09.nodes.exprs.comparisons; 2 | 3 | import com.endoflineblog.truffle.part_09.nodes.exprs.BinaryOperationExprNode; 4 | import com.oracle.truffle.api.dsl.Fallback; 5 | import com.oracle.truffle.api.dsl.Specialization; 6 | 7 | /** 8 | * Node class representing the lesser ({@code <}) operator. 9 | * Identical to the class with the same name from part 8. 10 | */ 11 | public abstract class LesserExprNode extends BinaryOperationExprNode { 12 | @Specialization 13 | protected boolean intLesser(int leftValue, int rightValue) { 14 | return leftValue < rightValue; 15 | } 16 | 17 | @Specialization(replaces = "intLesser") 18 | protected boolean doubleLesser(double leftValue, double rightValue) { 19 | return leftValue < rightValue; 20 | } 21 | 22 | @Fallback 23 | protected boolean objectLesser(Object leftValue, Object rightValue) { 24 | return false; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /part-10/src/main/java/com/endoflineblog/truffle/part_10/nodes/exprs/comparisons/LesserExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_10.nodes.exprs.comparisons; 2 | 3 | import com.endoflineblog.truffle.part_10.nodes.exprs.BinaryOperationExprNode; 4 | import com.oracle.truffle.api.dsl.Fallback; 5 | import com.oracle.truffle.api.dsl.Specialization; 6 | 7 | /** 8 | * Node class representing the lesser ({@code <}) operator. 9 | * Identical to the class with the same name from part 9. 10 | */ 11 | public abstract class LesserExprNode extends BinaryOperationExprNode { 12 | @Specialization 13 | protected boolean intLesser(int leftValue, int rightValue) { 14 | return leftValue < rightValue; 15 | } 16 | 17 | @Specialization(replaces = "intLesser") 18 | protected boolean doubleLesser(double leftValue, double rightValue) { 19 | return leftValue < rightValue; 20 | } 21 | 22 | @Fallback 23 | protected boolean objectLesser(Object leftValue, Object rightValue) { 24 | return false; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /part-05/src/main/java/com/endoflineblog/truffle/part_05/runtime/Undefined.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_05.runtime; 2 | 3 | import com.oracle.truffle.api.interop.InteropLibrary; 4 | import com.oracle.truffle.api.interop.TruffleObject; 5 | import com.oracle.truffle.api.library.ExportLibrary; 6 | import com.oracle.truffle.api.library.ExportMessage; 7 | 8 | /** 9 | * The class that represents the 'undefined' value in JavaScript. 10 | * It's a singleton. 11 | */ 12 | @ExportLibrary(InteropLibrary.class) 13 | public final class Undefined implements TruffleObject { 14 | public static final Undefined INSTANCE = new Undefined(); 15 | 16 | private Undefined() { 17 | } 18 | 19 | @ExportMessage 20 | boolean isNull() { 21 | return true; 22 | } 23 | 24 | @ExportMessage 25 | Object toDisplayString(@SuppressWarnings("unused") boolean allowSideEffects) { 26 | return this.toString(); 27 | } 28 | 29 | @Override 30 | public String toString() { 31 | return "undefined"; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /part-06/src/main/java/com/endoflineblog/truffle/part_06/EasyScriptTypeSystem.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_06; 2 | 3 | import com.oracle.truffle.api.dsl.ImplicitCast; 4 | import com.oracle.truffle.api.dsl.TypeSystem; 5 | 6 | /** 7 | * The {@link TypeSystem} for EasyScript. 8 | * Basically identical to the TypeSystem we've been using since part 3, 9 | * the only difference is that we pass the hierarchy of our primitives in the {@link TypeSystem#value} attribute. 10 | * Because of that, the Truffle DSL will generate a class, 11 | * {@link EasyScriptTypeSystemGen}, with methods like {@link EasyScriptTypeSystemGen#expectInteger} 12 | * and {@link EasyScriptTypeSystemGen#expectDouble}, 13 | * which we use in {@link com.endoflineblog.truffle.part_06.nodes.exprs.EasyScriptExprNode}. 14 | */ 15 | @TypeSystem({ 16 | int.class, 17 | double.class, 18 | }) 19 | public abstract class EasyScriptTypeSystem { 20 | @ImplicitCast 21 | public static double castIntToDouble(int value) { 22 | return value; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /part-08/src/main/java/com/endoflineblog/truffle/part_08/common/DeclarationKind.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_08.common; 2 | 3 | import com.endoflineblog.truffle.part_08.exceptions.EasyScriptException; 4 | 5 | /** 6 | * An enum that represents the different kinds of variable declarations in JavaScript. 7 | * Identical to the enum with the same name from part 7. 8 | */ 9 | public enum DeclarationKind { 10 | /** This represents the 'var' declaration kind. */ 11 | VAR, 12 | 13 | /** This represents the 'let' declaration kind. */ 14 | LET, 15 | 16 | /** This represents the 'const' declaration kind. */ 17 | CONST; 18 | 19 | public static DeclarationKind fromToken(String token) { 20 | switch (token) { 21 | case "var": return DeclarationKind.VAR; 22 | case "let": return DeclarationKind.LET; 23 | case "const": return DeclarationKind.CONST; 24 | default: throw new EasyScriptException("Unrecognized variable kind: '" + token + "'"); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /part-08/src/main/java/com/endoflineblog/truffle/part_08/parsing/ParsingResult.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_08.parsing; 2 | 3 | import com.endoflineblog.truffle.part_08.nodes.stmts.blocks.BlockStmtNode; 4 | import com.oracle.truffle.api.frame.FrameDescriptor; 5 | 6 | /** 7 | * The class used as the result of parsing in 8 | * {@link EasyScriptTruffleParser#parse}. 9 | */ 10 | public final class ParsingResult { 11 | /** The Node representing the list of statements that the EasyScript program consists of. */ 12 | public final BlockStmtNode programStmtBlock; 13 | 14 | /** 15 | * The {@link FrameDescriptor} used for the Truffle program itself 16 | * (which can contain local variables in this part). 17 | */ 18 | public final FrameDescriptor topLevelFrameDescriptor; 19 | 20 | public ParsingResult(BlockStmtNode programStmtBlock, FrameDescriptor topLevelFrameDescriptor) { 21 | this.programStmtBlock = programStmtBlock; 22 | this.topLevelFrameDescriptor = topLevelFrameDescriptor; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /part-09/src/main/java/com/endoflineblog/truffle/part_09/common/DeclarationKind.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_09.common; 2 | 3 | import com.endoflineblog.truffle.part_09.exceptions.EasyScriptException; 4 | 5 | /** 6 | * An enum that represents the different kinds of variable declarations in JavaScript. 7 | * Identical to the enum with the same name from part 8. 8 | */ 9 | public enum DeclarationKind { 10 | /** This represents the 'var' declaration kind. */ 11 | VAR, 12 | 13 | /** This represents the 'let' declaration kind. */ 14 | LET, 15 | 16 | /** This represents the 'const' declaration kind. */ 17 | CONST; 18 | 19 | public static DeclarationKind fromToken(String token) { 20 | switch (token) { 21 | case "var": return DeclarationKind.VAR; 22 | case "let": return DeclarationKind.LET; 23 | case "const": return DeclarationKind.CONST; 24 | default: throw new EasyScriptException("Unrecognized variable kind: '" + token + "'"); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /part-09/src/main/java/com/endoflineblog/truffle/part_09/nodes/exprs/comparisons/GreaterExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_09.nodes.exprs.comparisons; 2 | 3 | import com.endoflineblog.truffle.part_09.nodes.exprs.BinaryOperationExprNode; 4 | import com.oracle.truffle.api.dsl.Fallback; 5 | import com.oracle.truffle.api.dsl.Specialization; 6 | 7 | /** 8 | * Node class representing the greater ({@code >}) operator. 9 | * Identical to the class with the same name from part 8. 10 | */ 11 | public abstract class GreaterExprNode extends BinaryOperationExprNode { 12 | @Specialization 13 | protected boolean intGreater(int leftValue, int rightValue) { 14 | return leftValue > rightValue; 15 | } 16 | 17 | @Specialization(replaces = "intGreater") 18 | protected boolean doubleGreater(double leftValue, double rightValue) { 19 | return leftValue > rightValue; 20 | } 21 | 22 | @Fallback 23 | protected boolean objectGreater(Object leftValue, Object rightValue) { 24 | return false; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /part-10/src/main/java/com/endoflineblog/truffle/part_10/common/DeclarationKind.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_10.common; 2 | 3 | import com.endoflineblog.truffle.part_10.exceptions.EasyScriptException; 4 | 5 | /** 6 | * An enum that represents the different kinds of variable declarations in JavaScript. 7 | * Identical to the enum with the same name from part 9. 8 | */ 9 | public enum DeclarationKind { 10 | /** This represents the 'var' declaration kind. */ 11 | VAR, 12 | 13 | /** This represents the 'let' declaration kind. */ 14 | LET, 15 | 16 | /** This represents the 'const' declaration kind. */ 17 | CONST; 18 | 19 | public static DeclarationKind fromToken(String token) { 20 | switch (token) { 21 | case "var": return DeclarationKind.VAR; 22 | case "let": return DeclarationKind.LET; 23 | case "const": return DeclarationKind.CONST; 24 | default: throw new EasyScriptException("Unrecognized variable kind: '" + token + "'"); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /part-10/src/main/java/com/endoflineblog/truffle/part_10/nodes/exprs/comparisons/GreaterExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_10.nodes.exprs.comparisons; 2 | 3 | import com.endoflineblog.truffle.part_10.nodes.exprs.BinaryOperationExprNode; 4 | import com.oracle.truffle.api.dsl.Fallback; 5 | import com.oracle.truffle.api.dsl.Specialization; 6 | 7 | /** 8 | * Node class representing the greater ({@code >}) operator. 9 | * Identical to the class with the same name from part 9. 10 | */ 11 | public abstract class GreaterExprNode extends BinaryOperationExprNode { 12 | @Specialization 13 | protected boolean intGreater(int leftValue, int rightValue) { 14 | return leftValue > rightValue; 15 | } 16 | 17 | @Specialization(replaces = "intGreater") 18 | protected boolean doubleGreater(double leftValue, double rightValue) { 19 | return leftValue > rightValue; 20 | } 21 | 22 | @Fallback 23 | protected boolean objectGreater(Object leftValue, Object rightValue) { 24 | return false; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /part-11/src/main/java/com/endoflineblog/truffle/part_11/common/DeclarationKind.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_11.common; 2 | 3 | import com.endoflineblog.truffle.part_11.exceptions.EasyScriptException; 4 | 5 | /** 6 | * An enum that represents the different kinds of variable declarations in JavaScript. 7 | * Identical to the enum with the same name from part 10. 8 | */ 9 | public enum DeclarationKind { 10 | /** This represents the 'var' declaration kind. */ 11 | VAR, 12 | 13 | /** This represents the 'let' declaration kind. */ 14 | LET, 15 | 16 | /** This represents the 'const' declaration kind. */ 17 | CONST; 18 | 19 | public static DeclarationKind fromToken(String token) { 20 | switch (token) { 21 | case "var": return DeclarationKind.VAR; 22 | case "let": return DeclarationKind.LET; 23 | case "const": return DeclarationKind.CONST; 24 | default: throw new EasyScriptException("Unrecognized variable kind: '" + token + "'"); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /part-12/src/main/java/com/endoflineblog/truffle/part_12/common/DeclarationKind.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_12.common; 2 | 3 | import com.endoflineblog.truffle.part_12.exceptions.EasyScriptException; 4 | 5 | /** 6 | * An enum that represents the different kinds of variable declarations in JavaScript. 7 | * Identical to the enum with the same name from part 11. 8 | */ 9 | public enum DeclarationKind { 10 | /** This represents the 'var' declaration kind. */ 11 | VAR, 12 | 13 | /** This represents the 'let' declaration kind. */ 14 | LET, 15 | 16 | /** This represents the 'const' declaration kind. */ 17 | CONST; 18 | 19 | public static DeclarationKind fromToken(String token) { 20 | switch (token) { 21 | case "var": return DeclarationKind.VAR; 22 | case "let": return DeclarationKind.LET; 23 | case "const": return DeclarationKind.CONST; 24 | default: throw new EasyScriptException("Unrecognized variable kind: '" + token + "'"); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /part-13/src/main/java/com/endoflineblog/truffle/part_13/common/DeclarationKind.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_13.common; 2 | 3 | import com.endoflineblog.truffle.part_13.exceptions.EasyScriptException; 4 | 5 | /** 6 | * An enum that represents the different kinds of variable declarations in JavaScript. 7 | * Identical to the enum with the same name from part 12. 8 | */ 9 | public enum DeclarationKind { 10 | /** This represents the 'var' declaration kind. */ 11 | VAR, 12 | 13 | /** This represents the 'let' declaration kind. */ 14 | LET, 15 | 16 | /** This represents the 'const' declaration kind. */ 17 | CONST; 18 | 19 | public static DeclarationKind fromToken(String token) { 20 | switch (token) { 21 | case "var": return DeclarationKind.VAR; 22 | case "let": return DeclarationKind.LET; 23 | case "const": return DeclarationKind.CONST; 24 | default: throw new EasyScriptException("Unrecognized variable kind: '" + token + "'"); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /part-14/src/main/java/com/endoflineblog/truffle/part_14/common/DeclarationKind.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_14.common; 2 | 3 | import com.endoflineblog.truffle.part_14.exceptions.EasyScriptException; 4 | 5 | /** 6 | * An enum that represents the different kinds of variable declarations in JavaScript. 7 | * Identical to the enum with the same name from part 13. 8 | */ 9 | public enum DeclarationKind { 10 | /** This represents the 'var' declaration kind. */ 11 | VAR, 12 | 13 | /** This represents the 'let' declaration kind. */ 14 | LET, 15 | 16 | /** This represents the 'const' declaration kind. */ 17 | CONST; 18 | 19 | public static DeclarationKind fromToken(String token) { 20 | switch (token) { 21 | case "var": return DeclarationKind.VAR; 22 | case "let": return DeclarationKind.LET; 23 | case "const": return DeclarationKind.CONST; 24 | default: throw new EasyScriptException("Unrecognized variable kind: '" + token + "'"); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /part-15/src/main/java/com/endoflineblog/truffle/part_15/common/DeclarationKind.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_15.common; 2 | 3 | import com.endoflineblog.truffle.part_15.exceptions.EasyScriptException; 4 | 5 | /** 6 | * An enum that represents the different kinds of variable declarations in JavaScript. 7 | * Identical to the enum with the same name from part 14. 8 | */ 9 | public enum DeclarationKind { 10 | /** This represents the 'var' declaration kind. */ 11 | VAR, 12 | 13 | /** This represents the 'let' declaration kind. */ 14 | LET, 15 | 16 | /** This represents the 'const' declaration kind. */ 17 | CONST; 18 | 19 | public static DeclarationKind fromToken(String token) { 20 | switch (token) { 21 | case "var": return DeclarationKind.VAR; 22 | case "let": return DeclarationKind.LET; 23 | case "const": return DeclarationKind.CONST; 24 | default: throw new EasyScriptException("Unrecognized variable kind: '" + token + "'"); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /part-16/src/main/java/com/endoflineblog/truffle/part_16/common/DeclarationKind.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_16.common; 2 | 3 | import com.endoflineblog.truffle.part_16.exceptions.EasyScriptException; 4 | 5 | /** 6 | * An enum that represents the different kinds of variable declarations in JavaScript. 7 | * Identical to the enum with the same name from part 15. 8 | */ 9 | public enum DeclarationKind { 10 | /** This represents the 'var' declaration kind. */ 11 | VAR, 12 | 13 | /** This represents the 'let' declaration kind. */ 14 | LET, 15 | 16 | /** This represents the 'const' declaration kind. */ 17 | CONST; 18 | 19 | public static DeclarationKind fromToken(String token) { 20 | switch (token) { 21 | case "var": return DeclarationKind.VAR; 22 | case "let": return DeclarationKind.LET; 23 | case "const": return DeclarationKind.CONST; 24 | default: throw new EasyScriptException("Unrecognized variable kind: '" + token + "'"); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /part-06/src/main/java/com/endoflineblog/truffle/part_06/nodes/stmts/ExprStmtNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_06.nodes.stmts; 2 | 3 | import com.endoflineblog.truffle.part_06.nodes.exprs.EasyScriptExprNode; 4 | import com.oracle.truffle.api.frame.VirtualFrame; 5 | 6 | /** 7 | * A Node that represents an expression statement. 8 | * Identical to the class with the same name from part 5. 9 | */ 10 | public final class ExprStmtNode extends EasyScriptStmtNode { 11 | @SuppressWarnings("FieldMayBeFinal") 12 | @Child 13 | private EasyScriptExprNode expr; 14 | 15 | /** 16 | * Creates a new instance of the expression statement. 17 | * 18 | * @param expr the expression node 19 | */ 20 | public ExprStmtNode(EasyScriptExprNode expr) { 21 | this.expr = expr; 22 | } 23 | 24 | /** Evaluating the statement returns the result of executing its expression. */ 25 | @Override 26 | public Object executeStatement(VirtualFrame frame) { 27 | return this.expr.executeGeneric(frame); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /part-06/src/main/java/com/endoflineblog/truffle/part_06/nodes/exprs/GlobalVarReferenceExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_06.nodes.exprs; 2 | 3 | import com.endoflineblog.truffle.part_06.EasyScriptException; 4 | import com.oracle.truffle.api.dsl.NodeField; 5 | import com.oracle.truffle.api.dsl.Specialization; 6 | 7 | /** 8 | * A Node that represents the expression of referencing a global variable in EasyScript. 9 | * Identical to the class with the same name from part 5. 10 | */ 11 | @NodeField(name = "name", type = String.class) 12 | public abstract class GlobalVarReferenceExprNode extends EasyScriptExprNode { 13 | protected abstract String getName(); 14 | 15 | @Specialization 16 | protected Object readVariable() { 17 | String variableId = this.getName(); 18 | var value = this.currentLanguageContext().globalScopeObject.getVariable(variableId); 19 | if (value == null) { 20 | throw new EasyScriptException(this, "'" + variableId + "' is not defined"); 21 | } 22 | return value; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /part-07/src/main/java/com/endoflineblog/truffle/part_07/nodes/exprs/GlobalVarReferenceExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_07.nodes.exprs; 2 | 3 | import com.endoflineblog.truffle.part_07.EasyScriptException; 4 | import com.oracle.truffle.api.dsl.NodeField; 5 | import com.oracle.truffle.api.dsl.Specialization; 6 | 7 | /** 8 | * A Node that represents the expression of referencing a global variable in EasyScript. 9 | * Identical to the class with the same name from part 6. 10 | */ 11 | @NodeField(name = "name", type = String.class) 12 | public abstract class GlobalVarReferenceExprNode extends EasyScriptExprNode { 13 | protected abstract String getName(); 14 | 15 | @Specialization 16 | protected Object readVariable() { 17 | String variableId = this.getName(); 18 | var value = this.currentLanguageContext().globalScopeObject.getVariable(variableId); 19 | if (value == null) { 20 | throw new EasyScriptException(this, "'" + variableId + "' is not defined"); 21 | } 22 | return value; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /part-16/src/main/java/com/endoflineblog/truffle/part_16/nodes/stmts/controlflow/BreakStmtNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_16.nodes.stmts.controlflow; 2 | 3 | import com.endoflineblog.truffle.part_16.exceptions.BreakException; 4 | import com.endoflineblog.truffle.part_16.nodes.stmts.EasyScriptStmtNode; 5 | import com.oracle.truffle.api.frame.VirtualFrame; 6 | import com.oracle.truffle.api.source.SourceSection; 7 | 8 | /** 9 | * A Node representing the {@code break} statement. 10 | * Almost identical to the class with the same name from part 15, 11 | * the only difference is that we add a {@link SourceSection} 12 | * parameter to the constructor, which we pass to the constructor of the superclass, 13 | * {@link EasyScriptStmtNode}. 14 | */ 15 | public final class BreakStmtNode extends EasyScriptStmtNode { 16 | public BreakStmtNode(SourceSection sourceSection) { 17 | super(sourceSection); 18 | } 19 | 20 | @Override 21 | public Object executeStatement(VirtualFrame frame) { 22 | throw new BreakException(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /part-06/src/main/java/com/endoflineblog/truffle/part_06/runtime/Undefined.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_06.runtime; 2 | 3 | import com.oracle.truffle.api.interop.InteropLibrary; 4 | import com.oracle.truffle.api.interop.TruffleObject; 5 | import com.oracle.truffle.api.library.ExportLibrary; 6 | import com.oracle.truffle.api.library.ExportMessage; 7 | 8 | /** 9 | * The class that represents the 'undefined' value in JavaScript. 10 | * Identical to the class with the same name from part 5. 11 | */ 12 | @ExportLibrary(InteropLibrary.class) 13 | public final class Undefined implements TruffleObject { 14 | public static final Undefined INSTANCE = new Undefined(); 15 | 16 | private Undefined() { 17 | } 18 | 19 | @ExportMessage 20 | boolean isNull() { 21 | return true; 22 | } 23 | 24 | @ExportMessage 25 | Object toDisplayString(@SuppressWarnings("unused") boolean allowSideEffects) { 26 | return this.toString(); 27 | } 28 | 29 | @Override 30 | public String toString() { 31 | return "undefined"; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /part-07/src/main/java/com/endoflineblog/truffle/part_07/runtime/Undefined.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_07.runtime; 2 | 3 | import com.oracle.truffle.api.interop.InteropLibrary; 4 | import com.oracle.truffle.api.interop.TruffleObject; 5 | import com.oracle.truffle.api.library.ExportLibrary; 6 | import com.oracle.truffle.api.library.ExportMessage; 7 | 8 | /** 9 | * The class that represents the 'undefined' value in JavaScript. 10 | * Identical to the class with the same name from part 6. 11 | */ 12 | @ExportLibrary(InteropLibrary.class) 13 | public final class Undefined implements TruffleObject { 14 | public static final Undefined INSTANCE = new Undefined(); 15 | 16 | private Undefined() { 17 | } 18 | 19 | @ExportMessage 20 | boolean isNull() { 21 | return true; 22 | } 23 | 24 | @ExportMessage 25 | Object toDisplayString(@SuppressWarnings("unused") boolean allowSideEffects) { 26 | return this.toString(); 27 | } 28 | 29 | @Override 30 | public String toString() { 31 | return "undefined"; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /part-08/src/main/java/com/endoflineblog/truffle/part_08/runtime/Undefined.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_08.runtime; 2 | 3 | import com.oracle.truffle.api.interop.InteropLibrary; 4 | import com.oracle.truffle.api.interop.TruffleObject; 5 | import com.oracle.truffle.api.library.ExportLibrary; 6 | import com.oracle.truffle.api.library.ExportMessage; 7 | 8 | /** 9 | * The class that represents the 'undefined' value in JavaScript. 10 | * Identical to the class with the same name from part 7. 11 | */ 12 | @ExportLibrary(InteropLibrary.class) 13 | public final class Undefined implements TruffleObject { 14 | public static final Undefined INSTANCE = new Undefined(); 15 | 16 | private Undefined() { 17 | } 18 | 19 | @ExportMessage 20 | boolean isNull() { 21 | return true; 22 | } 23 | 24 | @ExportMessage 25 | Object toDisplayString(@SuppressWarnings("unused") boolean allowSideEffects) { 26 | return this.toString(); 27 | } 28 | 29 | @Override 30 | public String toString() { 31 | return "undefined"; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /part-09/src/main/java/com/endoflineblog/truffle/part_09/runtime/Undefined.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_09.runtime; 2 | 3 | import com.oracle.truffle.api.interop.InteropLibrary; 4 | import com.oracle.truffle.api.interop.TruffleObject; 5 | import com.oracle.truffle.api.library.ExportLibrary; 6 | import com.oracle.truffle.api.library.ExportMessage; 7 | 8 | /** 9 | * The class that represents the 'undefined' value in JavaScript. 10 | * Identical to the class with the same name from part 8. 11 | */ 12 | @ExportLibrary(InteropLibrary.class) 13 | public final class Undefined implements TruffleObject { 14 | public static final Undefined INSTANCE = new Undefined(); 15 | 16 | private Undefined() { 17 | } 18 | 19 | @ExportMessage 20 | boolean isNull() { 21 | return true; 22 | } 23 | 24 | @ExportMessage 25 | Object toDisplayString(@SuppressWarnings("unused") boolean allowSideEffects) { 26 | return this.toString(); 27 | } 28 | 29 | @Override 30 | public String toString() { 31 | return "undefined"; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /part-10/src/main/java/com/endoflineblog/truffle/part_10/runtime/Undefined.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_10.runtime; 2 | 3 | import com.oracle.truffle.api.interop.InteropLibrary; 4 | import com.oracle.truffle.api.interop.TruffleObject; 5 | import com.oracle.truffle.api.library.ExportLibrary; 6 | import com.oracle.truffle.api.library.ExportMessage; 7 | 8 | /** 9 | * The class that represents the 'undefined' value in JavaScript. 10 | * Identical to the class with the same name from part 9. 11 | */ 12 | @ExportLibrary(InteropLibrary.class) 13 | public final class Undefined implements TruffleObject { 14 | public static final Undefined INSTANCE = new Undefined(); 15 | 16 | private Undefined() { 17 | } 18 | 19 | @ExportMessage 20 | boolean isNull() { 21 | return true; 22 | } 23 | 24 | @ExportMessage 25 | Object toDisplayString(@SuppressWarnings("unused") boolean allowSideEffects) { 26 | return this.toString(); 27 | } 28 | 29 | @Override 30 | public String toString() { 31 | return "undefined"; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /part-16/src/main/java/com/endoflineblog/truffle/part_16/nodes/stmts/controlflow/ContinueStmtNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_16.nodes.stmts.controlflow; 2 | 3 | import com.endoflineblog.truffle.part_16.exceptions.ContinueException; 4 | import com.endoflineblog.truffle.part_16.nodes.stmts.EasyScriptStmtNode; 5 | import com.oracle.truffle.api.frame.VirtualFrame; 6 | import com.oracle.truffle.api.source.SourceSection; 7 | 8 | /** 9 | * A Node representing the {@code continue} statement. 10 | * Almost identical to the class with the same name from part 15, 11 | * the only difference is that we add a {@link SourceSection} 12 | * parameter to the constructor, which we pass to the constructor of the superclass, 13 | * {@link EasyScriptStmtNode}. 14 | */ 15 | public final class ContinueStmtNode extends EasyScriptStmtNode { 16 | public ContinueStmtNode(SourceSection sourceSection) { 17 | super(sourceSection); 18 | } 19 | 20 | @Override 21 | public Object executeStatement(VirtualFrame frame) { 22 | throw new ContinueException(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /part-03/src/main/java/com/endoflineblog/truffle/part_03/DoubleLiteralNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_03; 2 | 3 | import com.oracle.truffle.api.frame.VirtualFrame; 4 | import com.oracle.truffle.api.nodes.UnexpectedResultException; 5 | 6 | /** 7 | * The AST node that represents an decimal number literal expression in EasyScript. 8 | * Pretty much identical to {@link com.endoflineblog.truffle.part_02.DoubleLiteralNode}. 9 | */ 10 | public final class DoubleLiteralNode extends EasyScriptNode { 11 | private final double value; 12 | 13 | public DoubleLiteralNode(double value) { 14 | this.value = value; 15 | } 16 | 17 | @Override 18 | public double executeDouble(VirtualFrame frame) { 19 | return this.value; 20 | } 21 | 22 | @Override 23 | public Object executeGeneric(VirtualFrame frame) { 24 | return this.executeDouble(frame); 25 | } 26 | 27 | @Override 28 | public int executeInt(VirtualFrame frame) throws UnexpectedResultException { 29 | throw new UnexpectedResultException(this.value); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /part-05/src/main/java/com/endoflineblog/truffle/part_05/nodes/exprs/DoubleLiteralExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_05.nodes.exprs; 2 | 3 | import com.oracle.truffle.api.frame.VirtualFrame; 4 | import com.oracle.truffle.api.nodes.UnexpectedResultException; 5 | 6 | /** 7 | * The AST node that represents a decimal number literal expression in EasyScript. 8 | * The same as the DoubleLiteralNode in part 3. 9 | */ 10 | public final class DoubleLiteralExprNode extends EasyScriptExprNode { 11 | private final double value; 12 | 13 | public DoubleLiteralExprNode(double value) { 14 | this.value = value; 15 | } 16 | 17 | @Override 18 | public double executeDouble(VirtualFrame frame) { 19 | return this.value; 20 | } 21 | 22 | @Override 23 | public Object executeGeneric(VirtualFrame frame) { 24 | return this.executeDouble(frame); 25 | } 26 | 27 | @Override 28 | public int executeInt(VirtualFrame frame) throws UnexpectedResultException { 29 | throw new UnexpectedResultException(this.value); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /part-06/src/main/java/com/endoflineblog/truffle/part_06/nodes/exprs/UndefinedLiteralExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_06.nodes.exprs; 2 | 3 | import com.endoflineblog.truffle.part_06.runtime.Undefined; 4 | import com.oracle.truffle.api.frame.VirtualFrame; 5 | import com.oracle.truffle.api.nodes.UnexpectedResultException; 6 | 7 | /** 8 | * The AST node that represents the 'undefined' literal JavaScript expression. 9 | * Identical to the class with the same name from part 5. 10 | */ 11 | public final class UndefinedLiteralExprNode extends EasyScriptExprNode { 12 | @Override 13 | public int executeInt(VirtualFrame frame) throws UnexpectedResultException { 14 | throw new UnexpectedResultException(Undefined.INSTANCE); 15 | } 16 | 17 | @Override 18 | public double executeDouble(VirtualFrame frame) throws UnexpectedResultException { 19 | throw new UnexpectedResultException(Undefined.INSTANCE); 20 | } 21 | 22 | @Override 23 | public Object executeGeneric(VirtualFrame frame) { 24 | return Undefined.INSTANCE; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /part-07/src/main/java/com/endoflineblog/truffle/part_07/nodes/exprs/UndefinedLiteralExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_07.nodes.exprs; 2 | 3 | import com.endoflineblog.truffle.part_07.runtime.Undefined; 4 | import com.oracle.truffle.api.frame.VirtualFrame; 5 | import com.oracle.truffle.api.nodes.UnexpectedResultException; 6 | 7 | /** 8 | * The AST node that represents the 'undefined' literal JavaScript expression. 9 | * Identical to the class with the same name from part 6. 10 | */ 11 | public final class UndefinedLiteralExprNode extends EasyScriptExprNode { 12 | @Override 13 | public int executeInt(VirtualFrame frame) throws UnexpectedResultException { 14 | throw new UnexpectedResultException(Undefined.INSTANCE); 15 | } 16 | 17 | @Override 18 | public double executeDouble(VirtualFrame frame) throws UnexpectedResultException { 19 | throw new UnexpectedResultException(Undefined.INSTANCE); 20 | } 21 | 22 | @Override 23 | public Object executeGeneric(VirtualFrame frame) { 24 | return Undefined.INSTANCE; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /part-11/src/main/java/com/endoflineblog/truffle/part_11/runtime/Undefined.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_11.runtime; 2 | 3 | import com.oracle.truffle.api.interop.InteropLibrary; 4 | import com.oracle.truffle.api.interop.TruffleObject; 5 | import com.oracle.truffle.api.library.ExportLibrary; 6 | import com.oracle.truffle.api.library.ExportMessage; 7 | 8 | /** 9 | * The class that represents the 'undefined' value in JavaScript. 10 | * Identical to the class with the same name from part 10. 11 | */ 12 | @ExportLibrary(InteropLibrary.class) 13 | public final class Undefined implements TruffleObject { 14 | public static final Undefined INSTANCE = new Undefined(); 15 | 16 | private Undefined() { 17 | } 18 | 19 | @ExportMessage 20 | boolean isNull() { 21 | return true; 22 | } 23 | 24 | @ExportMessage 25 | Object toDisplayString(@SuppressWarnings("unused") boolean allowSideEffects) { 26 | return this.toString(); 27 | } 28 | 29 | @Override 30 | public String toString() { 31 | return "undefined"; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /part-12/src/main/java/com/endoflineblog/truffle/part_12/runtime/Undefined.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_12.runtime; 2 | 3 | import com.oracle.truffle.api.interop.InteropLibrary; 4 | import com.oracle.truffle.api.interop.TruffleObject; 5 | import com.oracle.truffle.api.library.ExportLibrary; 6 | import com.oracle.truffle.api.library.ExportMessage; 7 | 8 | /** 9 | * The class that represents the 'undefined' value in JavaScript. 10 | * Identical to the class with the same name from part 11. 11 | */ 12 | @ExportLibrary(InteropLibrary.class) 13 | public final class Undefined implements TruffleObject { 14 | public static final Undefined INSTANCE = new Undefined(); 15 | 16 | private Undefined() { 17 | } 18 | 19 | @ExportMessage 20 | boolean isNull() { 21 | return true; 22 | } 23 | 24 | @ExportMessage 25 | Object toDisplayString(@SuppressWarnings("unused") boolean allowSideEffects) { 26 | return this.toString(); 27 | } 28 | 29 | @Override 30 | public String toString() { 31 | return "undefined"; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /part-13/src/main/java/com/endoflineblog/truffle/part_13/runtime/Undefined.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_13.runtime; 2 | 3 | import com.oracle.truffle.api.interop.InteropLibrary; 4 | import com.oracle.truffle.api.interop.TruffleObject; 5 | import com.oracle.truffle.api.library.ExportLibrary; 6 | import com.oracle.truffle.api.library.ExportMessage; 7 | 8 | /** 9 | * The class that represents the 'undefined' value in JavaScript. 10 | * Identical to the class with the same name from part 12. 11 | */ 12 | @ExportLibrary(InteropLibrary.class) 13 | public final class Undefined implements TruffleObject { 14 | public static final Undefined INSTANCE = new Undefined(); 15 | 16 | private Undefined() { 17 | } 18 | 19 | @ExportMessage 20 | boolean isNull() { 21 | return true; 22 | } 23 | 24 | @ExportMessage 25 | Object toDisplayString(@SuppressWarnings("unused") boolean allowSideEffects) { 26 | return this.toString(); 27 | } 28 | 29 | @Override 30 | public String toString() { 31 | return "undefined"; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /part-14/src/main/java/com/endoflineblog/truffle/part_14/runtime/Undefined.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_14.runtime; 2 | 3 | import com.oracle.truffle.api.interop.InteropLibrary; 4 | import com.oracle.truffle.api.interop.TruffleObject; 5 | import com.oracle.truffle.api.library.ExportLibrary; 6 | import com.oracle.truffle.api.library.ExportMessage; 7 | 8 | /** 9 | * The class that represents the 'undefined' value in JavaScript. 10 | * Identical to the class with the same name from part 13. 11 | */ 12 | @ExportLibrary(InteropLibrary.class) 13 | public final class Undefined implements TruffleObject { 14 | public static final Undefined INSTANCE = new Undefined(); 15 | 16 | private Undefined() { 17 | } 18 | 19 | @ExportMessage 20 | boolean isNull() { 21 | return true; 22 | } 23 | 24 | @ExportMessage 25 | Object toDisplayString(@SuppressWarnings("unused") boolean allowSideEffects) { 26 | return this.toString(); 27 | } 28 | 29 | @Override 30 | public String toString() { 31 | return "undefined"; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /part-15/src/main/java/com/endoflineblog/truffle/part_15/runtime/Undefined.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_15.runtime; 2 | 3 | import com.oracle.truffle.api.interop.InteropLibrary; 4 | import com.oracle.truffle.api.interop.TruffleObject; 5 | import com.oracle.truffle.api.library.ExportLibrary; 6 | import com.oracle.truffle.api.library.ExportMessage; 7 | 8 | /** 9 | * The class that represents the 'undefined' value in JavaScript. 10 | * Identical to the class with the same name from part 14. 11 | */ 12 | @ExportLibrary(InteropLibrary.class) 13 | public final class Undefined implements TruffleObject { 14 | public static final Undefined INSTANCE = new Undefined(); 15 | 16 | private Undefined() { 17 | } 18 | 19 | @ExportMessage 20 | boolean isNull() { 21 | return true; 22 | } 23 | 24 | @ExportMessage 25 | Object toDisplayString(@SuppressWarnings("unused") boolean allowSideEffects) { 26 | return this.toString(); 27 | } 28 | 29 | @Override 30 | public String toString() { 31 | return "undefined"; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /part-16/src/main/java/com/endoflineblog/truffle/part_16/runtime/Undefined.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_16.runtime; 2 | 3 | import com.oracle.truffle.api.interop.InteropLibrary; 4 | import com.oracle.truffle.api.interop.TruffleObject; 5 | import com.oracle.truffle.api.library.ExportLibrary; 6 | import com.oracle.truffle.api.library.ExportMessage; 7 | 8 | /** 9 | * The class that represents the 'undefined' value in JavaScript. 10 | * Identical to the class with the same name from part 15. 11 | */ 12 | @ExportLibrary(InteropLibrary.class) 13 | public final class Undefined implements TruffleObject { 14 | public static final Undefined INSTANCE = new Undefined(); 15 | 16 | private Undefined() { 17 | } 18 | 19 | @ExportMessage 20 | boolean isNull() { 21 | return true; 22 | } 23 | 24 | @ExportMessage 25 | Object toDisplayString(@SuppressWarnings("unused") boolean allowSideEffects) { 26 | return this.toString(); 27 | } 28 | 29 | @Override 30 | public String toString() { 31 | return "undefined"; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /part-05/src/main/java/com/endoflineblog/truffle/part_05/nodes/exprs/GlobalVarAssignmentExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_05.nodes.exprs; 2 | 3 | import com.endoflineblog.truffle.part_05.EasyScriptException; 4 | import com.oracle.truffle.api.dsl.NodeChild; 5 | import com.oracle.truffle.api.dsl.NodeField; 6 | import com.oracle.truffle.api.dsl.Specialization; 7 | 8 | /** 9 | * A Node that represents the expression of assigning a value to a global variable in EasyScript. 10 | */ 11 | @NodeChild(value = "assignmentExpr") 12 | @NodeField(name = "name", type = String.class) 13 | public abstract class GlobalVarAssignmentExprNode extends EasyScriptExprNode { 14 | protected abstract String getName(); 15 | 16 | @Specialization 17 | protected Object assignVariable(Object value) { 18 | String variableId = this.getName(); 19 | if (!this.currentLanguageContext().globalScopeObject.updateVariable(variableId, value)) { 20 | throw new EasyScriptException(this, "'" + variableId + "' is not defined"); 21 | } 22 | return value; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /part-06/src/main/java/com/endoflineblog/truffle/part_06/nodes/FunctionRootNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_06.nodes; 2 | 3 | import com.endoflineblog.truffle.part_06.EasyScriptTruffleLanguage; 4 | import com.endoflineblog.truffle.part_06.nodes.exprs.EasyScriptExprNode; 5 | import com.oracle.truffle.api.frame.VirtualFrame; 6 | import com.oracle.truffle.api.nodes.RootNode; 7 | 8 | /** 9 | * The {@link RootNode} for our built-in functions. 10 | * Simply wraps the Node representing the body of the function. 11 | */ 12 | public final class FunctionRootNode extends RootNode { 13 | @SuppressWarnings("FieldMayBeFinal") 14 | @Child 15 | private EasyScriptExprNode functionBodyExpr; 16 | 17 | public FunctionRootNode(EasyScriptTruffleLanguage truffleLanguage, 18 | EasyScriptExprNode functionBodyExpr) { 19 | super(truffleLanguage); 20 | this.functionBodyExpr = functionBodyExpr; 21 | } 22 | 23 | @Override 24 | public Object execute(VirtualFrame frame) { 25 | return this.functionBodyExpr.executeGeneric(frame); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /part-06/src/main/java/com/endoflineblog/truffle/part_06/nodes/exprs/DoubleLiteralExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_06.nodes.exprs; 2 | 3 | import com.oracle.truffle.api.frame.VirtualFrame; 4 | import com.oracle.truffle.api.nodes.UnexpectedResultException; 5 | 6 | /** 7 | * The AST node that represents a decimal number literal expression in EasyScript. 8 | * Identical to the class with the same name from part 5. 9 | */ 10 | public final class DoubleLiteralExprNode extends EasyScriptExprNode { 11 | private final double value; 12 | 13 | public DoubleLiteralExprNode(double value) { 14 | this.value = value; 15 | } 16 | 17 | @Override 18 | public double executeDouble(VirtualFrame frame) { 19 | return this.value; 20 | } 21 | 22 | @Override 23 | public Object executeGeneric(VirtualFrame frame) { 24 | return this.executeDouble(frame); 25 | } 26 | 27 | @Override 28 | public int executeInt(VirtualFrame frame) throws UnexpectedResultException { 29 | throw new UnexpectedResultException(this.value); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /part-07/src/main/java/com/endoflineblog/truffle/part_07/nodes/exprs/DoubleLiteralExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_07.nodes.exprs; 2 | 3 | import com.oracle.truffle.api.frame.VirtualFrame; 4 | import com.oracle.truffle.api.nodes.UnexpectedResultException; 5 | 6 | /** 7 | * The AST node that represents a decimal number literal expression in EasyScript. 8 | * Identical to the class with the same name from part 6. 9 | */ 10 | public final class DoubleLiteralExprNode extends EasyScriptExprNode { 11 | private final double value; 12 | 13 | public DoubleLiteralExprNode(double value) { 14 | this.value = value; 15 | } 16 | 17 | @Override 18 | public double executeDouble(VirtualFrame frame) { 19 | return this.value; 20 | } 21 | 22 | @Override 23 | public Object executeGeneric(VirtualFrame frame) { 24 | return this.executeDouble(frame); 25 | } 26 | 27 | @Override 28 | public int executeInt(VirtualFrame frame) throws UnexpectedResultException { 29 | throw new UnexpectedResultException(this.value); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /part-09/src/main/java/com/endoflineblog/truffle/part_09/nodes/exprs/comparisons/LesserOrEqualExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_09.nodes.exprs.comparisons; 2 | 3 | import com.endoflineblog.truffle.part_09.nodes.exprs.BinaryOperationExprNode; 4 | import com.oracle.truffle.api.dsl.Fallback; 5 | import com.oracle.truffle.api.dsl.Specialization; 6 | 7 | /** 8 | * Node class representing the lesser or equal ({@code <=}) operator. 9 | * Identical to the class with the same name from part 8. 10 | */ 11 | public abstract class LesserOrEqualExprNode extends BinaryOperationExprNode { 12 | @Specialization 13 | protected boolean intLesserOrEqual(int leftValue, int rightValue) { 14 | return leftValue <= rightValue; 15 | } 16 | 17 | @Specialization(replaces = "intLesserOrEqual") 18 | protected boolean doubleLesserOrEqual(double leftValue, double rightValue) { 19 | return leftValue <= rightValue; 20 | } 21 | 22 | @Fallback 23 | protected boolean objectLesserOrEqual(Object leftValue, Object rightValue) { 24 | return false; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /part-10/src/main/java/com/endoflineblog/truffle/part_10/nodes/exprs/comparisons/LesserOrEqualExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_10.nodes.exprs.comparisons; 2 | 3 | import com.endoflineblog.truffle.part_10.nodes.exprs.BinaryOperationExprNode; 4 | import com.oracle.truffle.api.dsl.Fallback; 5 | import com.oracle.truffle.api.dsl.Specialization; 6 | 7 | /** 8 | * Node class representing the lesser or equal ({@code <=}) operator. 9 | * Identical to the class with the same name from part 9. 10 | */ 11 | public abstract class LesserOrEqualExprNode extends BinaryOperationExprNode { 12 | @Specialization 13 | protected boolean intLesserOrEqual(int leftValue, int rightValue) { 14 | return leftValue <= rightValue; 15 | } 16 | 17 | @Specialization(replaces = "intLesserOrEqual") 18 | protected boolean doubleLesserOrEqual(double leftValue, double rightValue) { 19 | return leftValue <= rightValue; 20 | } 21 | 22 | @Fallback 23 | protected boolean objectLesserOrEqual(Object leftValue, Object rightValue) { 24 | return false; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /part-09/src/main/java/com/endoflineblog/truffle/part_09/nodes/exprs/comparisons/GreaterOrEqualExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_09.nodes.exprs.comparisons; 2 | 3 | import com.endoflineblog.truffle.part_09.nodes.exprs.BinaryOperationExprNode; 4 | import com.oracle.truffle.api.dsl.Fallback; 5 | import com.oracle.truffle.api.dsl.Specialization; 6 | 7 | /** 8 | * Node class representing the greater or equal ({@code >=}) operator. 9 | * Identical to the class with the same name from part 8. 10 | */ 11 | public abstract class GreaterOrEqualExprNode extends BinaryOperationExprNode { 12 | @Specialization 13 | protected boolean intGreaterOrEqual(int leftValue, int rightValue) { 14 | return leftValue >= rightValue; 15 | } 16 | 17 | @Specialization(replaces = "intGreaterOrEqual") 18 | protected boolean doubleGreaterOrEqual(double leftValue, double rightValue) { 19 | return leftValue >= rightValue; 20 | } 21 | 22 | @Fallback 23 | protected boolean objectGreaterOrEqual(Object leftValue, Object rightValue) { 24 | return false; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /part-09/src/main/java/com/endoflineblog/truffle/part_09/nodes/stmts/controlflow/ReturnStmtNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_09.nodes.stmts.controlflow; 2 | 3 | import com.endoflineblog.truffle.part_09.exceptions.ReturnException; 4 | import com.endoflineblog.truffle.part_09.nodes.exprs.EasyScriptExprNode; 5 | import com.endoflineblog.truffle.part_09.nodes.stmts.EasyScriptStmtNode; 6 | import com.oracle.truffle.api.frame.VirtualFrame; 7 | 8 | /** 9 | * A Node representing the {@code return} statement. 10 | * Identical to the class with the same name from part 8. 11 | */ 12 | public final class ReturnStmtNode extends EasyScriptStmtNode { 13 | @SuppressWarnings("FieldMayBeFinal") 14 | @Child 15 | private EasyScriptExprNode returnExpr; 16 | 17 | public ReturnStmtNode(EasyScriptExprNode returnExpr) { 18 | this.returnExpr = returnExpr; 19 | } 20 | 21 | @Override 22 | public Object executeStatement(VirtualFrame frame) { 23 | Object returnValue = this.returnExpr.executeGeneric(frame); 24 | throw new ReturnException(returnValue); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /part-10/src/main/java/com/endoflineblog/truffle/part_10/nodes/exprs/comparisons/GreaterOrEqualExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_10.nodes.exprs.comparisons; 2 | 3 | import com.endoflineblog.truffle.part_10.nodes.exprs.BinaryOperationExprNode; 4 | import com.oracle.truffle.api.dsl.Fallback; 5 | import com.oracle.truffle.api.dsl.Specialization; 6 | 7 | /** 8 | * Node class representing the greater or equal ({@code >=}) operator. 9 | * Identical to the class with the same name from part 9. 10 | */ 11 | public abstract class GreaterOrEqualExprNode extends BinaryOperationExprNode { 12 | @Specialization 13 | protected boolean intGreaterOrEqual(int leftValue, int rightValue) { 14 | return leftValue >= rightValue; 15 | } 16 | 17 | @Specialization(replaces = "intGreaterOrEqual") 18 | protected boolean doubleGreaterOrEqual(double leftValue, double rightValue) { 19 | return leftValue >= rightValue; 20 | } 21 | 22 | @Fallback 23 | protected boolean objectGreaterOrEqual(Object leftValue, Object rightValue) { 24 | return false; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /part-10/src/main/java/com/endoflineblog/truffle/part_10/nodes/stmts/controlflow/ReturnStmtNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_10.nodes.stmts.controlflow; 2 | 3 | import com.endoflineblog.truffle.part_10.exceptions.ReturnException; 4 | import com.endoflineblog.truffle.part_10.nodes.exprs.EasyScriptExprNode; 5 | import com.endoflineblog.truffle.part_10.nodes.stmts.EasyScriptStmtNode; 6 | import com.oracle.truffle.api.frame.VirtualFrame; 7 | 8 | /** 9 | * A Node representing the {@code return} statement. 10 | * Identical to the class with the same name from part 9. 11 | */ 12 | public final class ReturnStmtNode extends EasyScriptStmtNode { 13 | @SuppressWarnings("FieldMayBeFinal") 14 | @Child 15 | private EasyScriptExprNode returnExpr; 16 | 17 | public ReturnStmtNode(EasyScriptExprNode returnExpr) { 18 | this.returnExpr = returnExpr; 19 | } 20 | 21 | @Override 22 | public Object executeStatement(VirtualFrame frame) { 23 | Object returnValue = this.returnExpr.executeGeneric(frame); 24 | throw new ReturnException(returnValue); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /part-11/src/main/java/com/endoflineblog/truffle/part_11/nodes/stmts/controlflow/ReturnStmtNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_11.nodes.stmts.controlflow; 2 | 3 | import com.endoflineblog.truffle.part_11.exceptions.ReturnException; 4 | import com.endoflineblog.truffle.part_11.nodes.exprs.EasyScriptExprNode; 5 | import com.endoflineblog.truffle.part_11.nodes.stmts.EasyScriptStmtNode; 6 | import com.oracle.truffle.api.frame.VirtualFrame; 7 | 8 | /** 9 | * A Node representing the {@code return} statement. 10 | * Identical to the class with the same name from part 10. 11 | */ 12 | public final class ReturnStmtNode extends EasyScriptStmtNode { 13 | @SuppressWarnings("FieldMayBeFinal") 14 | @Child 15 | private EasyScriptExprNode returnExpr; 16 | 17 | public ReturnStmtNode(EasyScriptExprNode returnExpr) { 18 | this.returnExpr = returnExpr; 19 | } 20 | 21 | @Override 22 | public Object executeStatement(VirtualFrame frame) { 23 | Object returnValue = this.returnExpr.executeGeneric(frame); 24 | throw new ReturnException(returnValue); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /part-11/src/main/java/com/endoflineblog/truffle/part_11/runtime/StringPrototype.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_11.runtime; 2 | 3 | import com.oracle.truffle.api.CallTarget; 4 | 5 | /** 6 | * The object containing the {@code CallTarget}s 7 | * for the built-in methods of strings. 8 | * Used in the expression Node for reading {@code TruffleString} properties. 9 | * Nodes access it through the {@code TruffleLanguageContext}'s {@code stringPrototype} field. 10 | * 11 | * @see com.endoflineblog.truffle.part_11.nodes.exprs.strings.ReadTruffleStringPropertyNode 12 | * @see com.endoflineblog.truffle.part_11.EasyScriptLanguageContext#stringPrototype 13 | */ 14 | public final class StringPrototype { 15 | /** 16 | * The {@link CallTarget} for the {@code charAt()} string method. 17 | * 18 | * @see com.endoflineblog.truffle.part_11.nodes.exprs.functions.built_in.methods.CharAtMethodBodyExprNode 19 | */ 20 | public final CallTarget charAtMethod; 21 | 22 | public StringPrototype(CallTarget charAtMethod) { 23 | this.charAtMethod = charAtMethod; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /part-12/src/main/java/com/endoflineblog/truffle/part_12/nodes/exprs/properties/PropertyReadExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_12.nodes.exprs.properties; 2 | 3 | import com.endoflineblog.truffle.part_12.nodes.exprs.EasyScriptExprNode; 4 | import com.oracle.truffle.api.dsl.Cached; 5 | import com.oracle.truffle.api.dsl.NodeChild; 6 | import com.oracle.truffle.api.dsl.NodeField; 7 | import com.oracle.truffle.api.dsl.Specialization; 8 | 9 | /** 10 | * The Node for reading properties of objects. 11 | * Used in code like {@code t.myProp}. 12 | * Identical to the class with the same name from part 11. 13 | */ 14 | @NodeChild("targetExpr") 15 | @NodeField(name = "propertyName", type = String.class) 16 | public abstract class PropertyReadExprNode extends EasyScriptExprNode { 17 | protected abstract String getPropertyName(); 18 | 19 | @Specialization 20 | protected Object readProperty(Object target, 21 | @Cached CommonReadPropertyNode commonReadPropertyNode) { 22 | return commonReadPropertyNode.executeReadProperty(target, this.getPropertyName()); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /part-12/src/main/java/com/endoflineblog/truffle/part_12/nodes/stmts/controlflow/ReturnStmtNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_12.nodes.stmts.controlflow; 2 | 3 | import com.endoflineblog.truffle.part_12.exceptions.ReturnException; 4 | import com.endoflineblog.truffle.part_12.nodes.exprs.EasyScriptExprNode; 5 | import com.endoflineblog.truffle.part_12.nodes.stmts.EasyScriptStmtNode; 6 | import com.oracle.truffle.api.frame.VirtualFrame; 7 | 8 | /** 9 | * A Node representing the {@code return} statement. 10 | * Identical to the class with the same name from part 11. 11 | */ 12 | public final class ReturnStmtNode extends EasyScriptStmtNode { 13 | @SuppressWarnings("FieldMayBeFinal") 14 | @Child 15 | private EasyScriptExprNode returnExpr; 16 | 17 | public ReturnStmtNode(EasyScriptExprNode returnExpr) { 18 | this.returnExpr = returnExpr; 19 | } 20 | 21 | @Override 22 | public Object executeStatement(VirtualFrame frame) { 23 | Object returnValue = this.returnExpr.executeGeneric(frame); 24 | throw new ReturnException(returnValue); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /part-13/src/main/java/com/endoflineblog/truffle/part_13/nodes/stmts/controlflow/ReturnStmtNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_13.nodes.stmts.controlflow; 2 | 3 | import com.endoflineblog.truffle.part_13.exceptions.ReturnException; 4 | import com.endoflineblog.truffle.part_13.nodes.exprs.EasyScriptExprNode; 5 | import com.endoflineblog.truffle.part_13.nodes.stmts.EasyScriptStmtNode; 6 | import com.oracle.truffle.api.frame.VirtualFrame; 7 | 8 | /** 9 | * A Node representing the {@code return} statement. 10 | * Identical to the class with the same name from part 12. 11 | */ 12 | public final class ReturnStmtNode extends EasyScriptStmtNode { 13 | @SuppressWarnings("FieldMayBeFinal") 14 | @Child 15 | private EasyScriptExprNode returnExpr; 16 | 17 | public ReturnStmtNode(EasyScriptExprNode returnExpr) { 18 | this.returnExpr = returnExpr; 19 | } 20 | 21 | @Override 22 | public Object executeStatement(VirtualFrame frame) { 23 | Object returnValue = this.returnExpr.executeGeneric(frame); 24 | throw new ReturnException(returnValue); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /part-14/src/main/java/com/endoflineblog/truffle/part_14/nodes/stmts/controlflow/ReturnStmtNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_14.nodes.stmts.controlflow; 2 | 3 | import com.endoflineblog.truffle.part_14.exceptions.ReturnException; 4 | import com.endoflineblog.truffle.part_14.nodes.exprs.EasyScriptExprNode; 5 | import com.endoflineblog.truffle.part_14.nodes.stmts.EasyScriptStmtNode; 6 | import com.oracle.truffle.api.frame.VirtualFrame; 7 | 8 | /** 9 | * A Node representing the {@code return} statement. 10 | * Identical to the class with the same name from part 13. 11 | */ 12 | public final class ReturnStmtNode extends EasyScriptStmtNode { 13 | @SuppressWarnings("FieldMayBeFinal") 14 | @Child 15 | private EasyScriptExprNode returnExpr; 16 | 17 | public ReturnStmtNode(EasyScriptExprNode returnExpr) { 18 | this.returnExpr = returnExpr; 19 | } 20 | 21 | @Override 22 | public Object executeStatement(VirtualFrame frame) { 23 | Object returnValue = this.returnExpr.executeGeneric(frame); 24 | throw new ReturnException(returnValue); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /part-09/src/main/java/com/endoflineblog/truffle/part_09/parsing/ParsingResult.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_09.parsing; 2 | 3 | import com.endoflineblog.truffle.part_09.nodes.stmts.blocks.BlockStmtNode; 4 | import com.oracle.truffle.api.frame.FrameDescriptor; 5 | 6 | /** 7 | * The class used as the result of parsing in 8 | * {@link EasyScriptTruffleParser#parse}. 9 | * Identical to the class with the same name from part 8. 10 | */ 11 | public final class ParsingResult { 12 | /** The Node representing the list of statements that the EasyScript program consists of. */ 13 | public final BlockStmtNode programStmtBlock; 14 | 15 | /** 16 | * The {@link FrameDescriptor} used for the Truffle program itself 17 | * (which can contain local variables in this part). 18 | */ 19 | public final FrameDescriptor topLevelFrameDescriptor; 20 | 21 | public ParsingResult(BlockStmtNode programStmtBlock, FrameDescriptor topLevelFrameDescriptor) { 22 | this.programStmtBlock = programStmtBlock; 23 | this.topLevelFrameDescriptor = topLevelFrameDescriptor; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /part-10/src/main/java/com/endoflineblog/truffle/part_10/parsing/ParsingResult.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_10.parsing; 2 | 3 | import com.endoflineblog.truffle.part_10.nodes.stmts.blocks.BlockStmtNode; 4 | import com.oracle.truffle.api.frame.FrameDescriptor; 5 | 6 | /** 7 | * The class used as the result of parsing in 8 | * {@link EasyScriptTruffleParser#parse}. 9 | * Identical to the class with the same name from part 9. 10 | */ 11 | public final class ParsingResult { 12 | /** The Node representing the list of statements that the EasyScript program consists of. */ 13 | public final BlockStmtNode programStmtBlock; 14 | 15 | /** 16 | * The {@link FrameDescriptor} used for the Truffle program itself 17 | * (which can contain local variables in this part). 18 | */ 19 | public final FrameDescriptor topLevelFrameDescriptor; 20 | 21 | public ParsingResult(BlockStmtNode programStmtBlock, FrameDescriptor topLevelFrameDescriptor) { 22 | this.programStmtBlock = programStmtBlock; 23 | this.topLevelFrameDescriptor = topLevelFrameDescriptor; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /part-11/src/main/java/com/endoflineblog/truffle/part_11/parsing/ParsingResult.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_11.parsing; 2 | 3 | import com.endoflineblog.truffle.part_11.nodes.stmts.blocks.BlockStmtNode; 4 | import com.oracle.truffle.api.frame.FrameDescriptor; 5 | 6 | /** 7 | * The class used as the result of parsing in 8 | * {@link EasyScriptTruffleParser#parse}. 9 | * Identical to the class with the same name from part 10. 10 | */ 11 | public final class ParsingResult { 12 | /** The Node representing the list of statements that the EasyScript program consists of. */ 13 | public final BlockStmtNode programStmtBlock; 14 | 15 | /** 16 | * The {@link FrameDescriptor} used for the Truffle program itself 17 | * (which can contain local variables in this part). 18 | */ 19 | public final FrameDescriptor topLevelFrameDescriptor; 20 | 21 | public ParsingResult(BlockStmtNode programStmtBlock, FrameDescriptor topLevelFrameDescriptor) { 22 | this.programStmtBlock = programStmtBlock; 23 | this.topLevelFrameDescriptor = topLevelFrameDescriptor; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /part-12/src/main/java/com/endoflineblog/truffle/part_12/parsing/ParsingResult.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_12.parsing; 2 | 3 | import com.endoflineblog.truffle.part_12.nodes.stmts.blocks.BlockStmtNode; 4 | import com.oracle.truffle.api.frame.FrameDescriptor; 5 | 6 | /** 7 | * The class used as the result of parsing in 8 | * {@link EasyScriptTruffleParser#parse}. 9 | * Identical to the class with the same name from part 11. 10 | */ 11 | public final class ParsingResult { 12 | /** The Node representing the list of statements that the EasyScript program consists of. */ 13 | public final BlockStmtNode programStmtBlock; 14 | 15 | /** 16 | * The {@link FrameDescriptor} used for the Truffle program itself 17 | * (which can contain local variables in this part). 18 | */ 19 | public final FrameDescriptor topLevelFrameDescriptor; 20 | 21 | public ParsingResult(BlockStmtNode programStmtBlock, FrameDescriptor topLevelFrameDescriptor) { 22 | this.programStmtBlock = programStmtBlock; 23 | this.topLevelFrameDescriptor = topLevelFrameDescriptor; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /part-12/src/test/java/com/endoflineblog/truffle/part_12/ParsingTest.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_12; 2 | 3 | import org.graalvm.polyglot.Context; 4 | import org.junit.jupiter.api.AfterEach; 5 | import org.junit.jupiter.api.BeforeEach; 6 | import org.junit.jupiter.api.Test; 7 | 8 | /** 9 | * This is a set of unit tests for validating parsing edge cases 10 | * (mainly relating to the {@code new} operator) in EasyScript. 11 | */ 12 | class ParsingTest { 13 | private Context context; 14 | 15 | @BeforeEach 16 | void setUp() { 17 | this.context = Context.create(); 18 | } 19 | 20 | @AfterEach 21 | void tearDown() { 22 | this.context.close(); 23 | } 24 | 25 | @Test 26 | void multiple_calls_of_calls_are_parsed() { 27 | this.context.parse("ezs", "a()()()"); 28 | } 29 | 30 | @Test 31 | void property_reads_of_property_reads_are_parsed() { 32 | this.context.parse("ezs", "a.b.c"); 33 | } 34 | 35 | @Test 36 | void method_calls_of_calls_are_parsed() { 37 | this.context.parse("ezs", "a().b().c()"); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /part-13/src/main/java/com/endoflineblog/truffle/part_13/parsing/ParsingResult.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_13.parsing; 2 | 3 | import com.endoflineblog.truffle.part_13.nodes.stmts.blocks.BlockStmtNode; 4 | import com.oracle.truffle.api.frame.FrameDescriptor; 5 | 6 | /** 7 | * The class used as the result of parsing in 8 | * {@link EasyScriptTruffleParser#parse}. 9 | * Identical to the class with the same name from part 12. 10 | */ 11 | public final class ParsingResult { 12 | /** The Node representing the list of statements that the EasyScript program consists of. */ 13 | public final BlockStmtNode programStmtBlock; 14 | 15 | /** 16 | * The {@link FrameDescriptor} used for the Truffle program itself 17 | * (which can contain local variables in this part). 18 | */ 19 | public final FrameDescriptor topLevelFrameDescriptor; 20 | 21 | public ParsingResult(BlockStmtNode programStmtBlock, FrameDescriptor topLevelFrameDescriptor) { 22 | this.programStmtBlock = programStmtBlock; 23 | this.topLevelFrameDescriptor = topLevelFrameDescriptor; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /part-13/src/test/java/com/endoflineblog/truffle/part_13/ParsingTest.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_13; 2 | 3 | import org.graalvm.polyglot.Context; 4 | import org.junit.jupiter.api.AfterEach; 5 | import org.junit.jupiter.api.BeforeEach; 6 | import org.junit.jupiter.api.Test; 7 | 8 | /** 9 | * This is a set of unit tests for validating parsing edge cases 10 | * (mainly relating to the {@code new} operator) in EasyScript. 11 | */ 12 | class ParsingTest { 13 | private Context context; 14 | 15 | @BeforeEach 16 | void setUp() { 17 | this.context = Context.create(); 18 | } 19 | 20 | @AfterEach 21 | void tearDown() { 22 | this.context.close(); 23 | } 24 | 25 | @Test 26 | void multiple_calls_of_calls_are_parsed() { 27 | this.context.parse("ezs", "a()()()"); 28 | } 29 | 30 | @Test 31 | void property_reads_of_property_reads_are_parsed() { 32 | this.context.parse("ezs", "a.b.c"); 33 | } 34 | 35 | @Test 36 | void method_calls_of_calls_are_parsed() { 37 | this.context.parse("ezs", "a().b().c()"); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /part-14/src/main/java/com/endoflineblog/truffle/part_14/parsing/ParsingResult.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_14.parsing; 2 | 3 | import com.endoflineblog.truffle.part_14.nodes.stmts.blocks.BlockStmtNode; 4 | import com.oracle.truffle.api.frame.FrameDescriptor; 5 | 6 | /** 7 | * The class used as the result of parsing in 8 | * {@link EasyScriptTruffleParser#parse}. 9 | * Identical to the class with the same name from part 13. 10 | */ 11 | public final class ParsingResult { 12 | /** The Node representing the list of statements that the EasyScript program consists of. */ 13 | public final BlockStmtNode programStmtBlock; 14 | 15 | /** 16 | * The {@link FrameDescriptor} used for the Truffle program itself 17 | * (which can contain local variables in this part). 18 | */ 19 | public final FrameDescriptor topLevelFrameDescriptor; 20 | 21 | public ParsingResult(BlockStmtNode programStmtBlock, FrameDescriptor topLevelFrameDescriptor) { 22 | this.programStmtBlock = programStmtBlock; 23 | this.topLevelFrameDescriptor = topLevelFrameDescriptor; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /part-14/src/test/java/com/endoflineblog/truffle/part_14/ParsingTest.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_14; 2 | 3 | import org.graalvm.polyglot.Context; 4 | import org.junit.jupiter.api.AfterEach; 5 | import org.junit.jupiter.api.BeforeEach; 6 | import org.junit.jupiter.api.Test; 7 | 8 | /** 9 | * This is a set of unit tests for validating parsing edge cases 10 | * (mainly relating to the {@code new} operator) in EasyScript. 11 | */ 12 | class ParsingTest { 13 | private Context context; 14 | 15 | @BeforeEach 16 | void setUp() { 17 | this.context = Context.create(); 18 | } 19 | 20 | @AfterEach 21 | void tearDown() { 22 | this.context.close(); 23 | } 24 | 25 | @Test 26 | void multiple_calls_of_calls_are_parsed() { 27 | this.context.parse("ezs", "a()()()"); 28 | } 29 | 30 | @Test 31 | void property_reads_of_property_reads_are_parsed() { 32 | this.context.parse("ezs", "a.b.c"); 33 | } 34 | 35 | @Test 36 | void method_calls_of_calls_are_parsed() { 37 | this.context.parse("ezs", "a().b().c()"); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /part-15/src/main/java/com/endoflineblog/truffle/part_15/parsing/ParsingResult.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_15.parsing; 2 | 3 | import com.endoflineblog.truffle.part_15.nodes.stmts.blocks.BlockStmtNode; 4 | import com.oracle.truffle.api.frame.FrameDescriptor; 5 | 6 | /** 7 | * The class used as the result of parsing in 8 | * {@link EasyScriptTruffleParser#parse}. 9 | * Identical to the class with the same name from part 14. 10 | */ 11 | public final class ParsingResult { 12 | /** The Node representing the list of statements that the EasyScript program consists of. */ 13 | public final BlockStmtNode programStmtBlock; 14 | 15 | /** 16 | * The {@link FrameDescriptor} used for the Truffle program itself 17 | * (which can contain local variables in this part). 18 | */ 19 | public final FrameDescriptor topLevelFrameDescriptor; 20 | 21 | public ParsingResult(BlockStmtNode programStmtBlock, FrameDescriptor topLevelFrameDescriptor) { 22 | this.programStmtBlock = programStmtBlock; 23 | this.topLevelFrameDescriptor = topLevelFrameDescriptor; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /part-15/src/test/java/com/endoflineblog/truffle/part_15/ParsingTest.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_15; 2 | 3 | import org.graalvm.polyglot.Context; 4 | import org.junit.jupiter.api.AfterEach; 5 | import org.junit.jupiter.api.BeforeEach; 6 | import org.junit.jupiter.api.Test; 7 | 8 | /** 9 | * This is a set of unit tests for validating parsing edge cases 10 | * (mainly relating to the {@code new} operator) in EasyScript. 11 | */ 12 | class ParsingTest { 13 | private Context context; 14 | 15 | @BeforeEach 16 | void setUp() { 17 | this.context = Context.create(); 18 | } 19 | 20 | @AfterEach 21 | void tearDown() { 22 | this.context.close(); 23 | } 24 | 25 | @Test 26 | void multiple_calls_of_calls_are_parsed() { 27 | this.context.parse("ezs", "a()()()"); 28 | } 29 | 30 | @Test 31 | void property_reads_of_property_reads_are_parsed() { 32 | this.context.parse("ezs", "a.b.c"); 33 | } 34 | 35 | @Test 36 | void method_calls_of_calls_are_parsed() { 37 | this.context.parse("ezs", "a().b().c()"); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /part-16/src/test/java/com/endoflineblog/truffle/part_16/ParsingTest.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_16; 2 | 3 | import org.graalvm.polyglot.Context; 4 | import org.junit.jupiter.api.AfterEach; 5 | import org.junit.jupiter.api.BeforeEach; 6 | import org.junit.jupiter.api.Test; 7 | 8 | /** 9 | * This is a set of unit tests for validating parsing edge cases 10 | * (mainly relating to the {@code new} operator) in EasyScript. 11 | */ 12 | class ParsingTest { 13 | private Context context; 14 | 15 | @BeforeEach 16 | void setUp() { 17 | this.context = Context.create(); 18 | } 19 | 20 | @AfterEach 21 | void tearDown() { 22 | this.context.close(); 23 | } 24 | 25 | @Test 26 | void multiple_calls_of_calls_are_parsed() { 27 | this.context.parse("ezs", "a()()()"); 28 | } 29 | 30 | @Test 31 | void property_reads_of_property_reads_are_parsed() { 32 | this.context.parse("ezs", "a.b.c"); 33 | } 34 | 35 | @Test 36 | void method_calls_of_calls_are_parsed() { 37 | this.context.parse("ezs", "a().b().c()"); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /part-11/src/main/java/com/endoflineblog/truffle/part_11/nodes/exprs/literals/StringLiteralExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_11.nodes.exprs.literals; 2 | 3 | import com.endoflineblog.truffle.part_11.nodes.exprs.EasyScriptExprNode; 4 | import com.endoflineblog.truffle.part_11.runtime.EasyScriptTruffleStrings; 5 | import com.oracle.truffle.api.frame.VirtualFrame; 6 | import com.oracle.truffle.api.strings.TruffleString; 7 | 8 | /** 9 | * The AST node that represents a string literal expression in EasyScript. 10 | */ 11 | public final class StringLiteralExprNode extends EasyScriptExprNode { 12 | private final TruffleString value; 13 | 14 | public StringLiteralExprNode(String value) { 15 | this.value = EasyScriptTruffleStrings.fromJavaString(value); 16 | } 17 | 18 | /** Empty strings are considered "falsy" in JavaScript. */ 19 | @Override 20 | public boolean executeBool(VirtualFrame frame) { 21 | return !this.value.isEmpty(); 22 | } 23 | 24 | @Override 25 | public TruffleString executeGeneric(VirtualFrame frame) { 26 | return this.value; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /part-05/src/main/antlr/com/endoflineblog/truffle/part_05/EasyScript.g4: -------------------------------------------------------------------------------- 1 | grammar EasyScript ; 2 | 3 | @header{ 4 | package com.endoflineblog.truffle.part_05; 5 | } 6 | 7 | start : stmt+ EOF ; 8 | 9 | stmt : kind=('var' | 'let' | 'const') binding (',' binding)* ';'? #DeclStmt 10 | | expr1 ';'? #ExprStmt 11 | ; 12 | binding : ID ('=' expr1)? ; 13 | 14 | expr1 : ID '=' expr1 #AssignmentExpr1 15 | | expr2 #PrecedenceTwoExpr1 16 | ; 17 | expr2 : left=expr2 '+' right=expr3 #AddExpr2 18 | | expr3 #PrecedenceThreeExpr2 19 | ; 20 | expr3 : literal #LiteralExpr3 21 | | ID #ReferenceExpr3 22 | | '(' expr1 ')' #PrecedenceOneExpr3 23 | ; 24 | 25 | literal : INT | DOUBLE | 'undefined' ; 26 | 27 | fragment DIGIT : [0-9] ; 28 | INT : DIGIT+ ; 29 | DOUBLE : DIGIT+ '.' DIGIT+ ; 30 | 31 | fragment LETTER : [a-zA-Z$_] ; 32 | ID : LETTER (LETTER | DIGIT)* ; 33 | 34 | // skip all whitespace 35 | WS : (' ' | '\r' | '\t' | '\n' | '\f')+ -> skip ; 36 | -------------------------------------------------------------------------------- /part-05/src/main/java/com/endoflineblog/truffle/part_05/EasyScriptException.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_05; 2 | 3 | import com.oracle.truffle.api.TruffleLanguage; 4 | import com.oracle.truffle.api.exception.AbstractTruffleException; 5 | import com.oracle.truffle.api.nodes.Node; 6 | 7 | /** 8 | * The exception that's thrown from the EasyScript implementation if any semantic errors are found. 9 | * Examples of errors are trying to reference a variable that has not been defined, 10 | * or re-assigning a 'const' variable. 11 | * 12 | * Note that exceptions thrown from {@link TruffleLanguage} need to extend the {@link AbstractTruffleException} 13 | * class in order to not be considered "internal errors" of the language implementation. 14 | * All other exceptions thrown are considered bugs of the implementation. 15 | */ 16 | public final class EasyScriptException extends AbstractTruffleException { 17 | public EasyScriptException(String message) { 18 | this(null, message); 19 | } 20 | 21 | public EasyScriptException(Node location, String message) { 22 | super(message, location); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /part-06/src/main/java/com/endoflineblog/truffle/part_06/EasyScriptLanguageContext.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_06; 2 | 3 | import com.endoflineblog.truffle.part_06.runtime.GlobalScopeObject; 4 | import com.oracle.truffle.api.TruffleLanguage; 5 | import com.oracle.truffle.api.nodes.Node; 6 | 7 | /** 8 | * The class of the context for the 9 | * {@link EasyScriptTruffleLanguage TruffleLanguage implementaton in this part of the series}. 10 | * Identical to the class with the same name from part 5. 11 | */ 12 | public final class EasyScriptLanguageContext { 13 | private static final TruffleLanguage.ContextReference REF = 14 | TruffleLanguage.ContextReference.create(EasyScriptTruffleLanguage.class); 15 | 16 | /** Retrieve the current language context for the given {@link Node}. */ 17 | public static EasyScriptLanguageContext get(Node node) { 18 | return REF.get(node); 19 | } 20 | 21 | public final GlobalScopeObject globalScopeObject; 22 | 23 | public EasyScriptLanguageContext() { 24 | this.globalScopeObject = new GlobalScopeObject(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /part-07/src/main/java/com/endoflineblog/truffle/part_07/EasyScriptLanguageContext.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_07; 2 | 3 | import com.endoflineblog.truffle.part_07.runtime.GlobalScopeObject; 4 | import com.oracle.truffle.api.TruffleLanguage; 5 | import com.oracle.truffle.api.nodes.Node; 6 | 7 | /** 8 | * The class of the context for the 9 | * {@link EasyScriptTruffleLanguage TruffleLanguage implementaton in this part of the series}. 10 | * Identical to the class with the same name from part 6. 11 | */ 12 | public final class EasyScriptLanguageContext { 13 | private static final TruffleLanguage.ContextReference REF = 14 | TruffleLanguage.ContextReference.create(EasyScriptTruffleLanguage.class); 15 | 16 | /** Retrieve the current language context for the given {@link Node}. */ 17 | public static EasyScriptLanguageContext get(Node node) { 18 | return REF.get(node); 19 | } 20 | 21 | public final GlobalScopeObject globalScopeObject; 22 | 23 | public EasyScriptLanguageContext() { 24 | this.globalScopeObject = new GlobalScopeObject(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /part-08/src/main/java/com/endoflineblog/truffle/part_08/EasyScriptLanguageContext.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_08; 2 | 3 | import com.endoflineblog.truffle.part_08.runtime.GlobalScopeObject; 4 | import com.oracle.truffle.api.TruffleLanguage; 5 | import com.oracle.truffle.api.nodes.Node; 6 | 7 | /** 8 | * The class of the context for the 9 | * {@link EasyScriptTruffleLanguage TruffleLanguage implementaton in this part of the series}. 10 | * Identical to the class with the same name from part 7. 11 | */ 12 | public final class EasyScriptLanguageContext { 13 | private static final TruffleLanguage.ContextReference REF = 14 | TruffleLanguage.ContextReference.create(EasyScriptTruffleLanguage.class); 15 | 16 | /** Retrieve the current language context for the given {@link Node}. */ 17 | public static EasyScriptLanguageContext get(Node node) { 18 | return REF.get(node); 19 | } 20 | 21 | public final GlobalScopeObject globalScopeObject; 22 | 23 | public EasyScriptLanguageContext() { 24 | this.globalScopeObject = new GlobalScopeObject(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /part-09/src/main/java/com/endoflineblog/truffle/part_09/EasyScriptLanguageContext.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_09; 2 | 3 | import com.endoflineblog.truffle.part_09.runtime.GlobalScopeObject; 4 | import com.oracle.truffle.api.TruffleLanguage; 5 | import com.oracle.truffle.api.nodes.Node; 6 | 7 | /** 8 | * The class of the context for the 9 | * {@link EasyScriptTruffleLanguage TruffleLanguage implementaton in this part of the series}. 10 | * Identical to the class with the same name from part 8. 11 | */ 12 | public final class EasyScriptLanguageContext { 13 | private static final TruffleLanguage.ContextReference REF = 14 | TruffleLanguage.ContextReference.create(EasyScriptTruffleLanguage.class); 15 | 16 | /** Retrieve the current language context for the given {@link Node}. */ 17 | public static EasyScriptLanguageContext get(Node node) { 18 | return REF.get(node); 19 | } 20 | 21 | public final GlobalScopeObject globalScopeObject; 22 | 23 | public EasyScriptLanguageContext() { 24 | this.globalScopeObject = new GlobalScopeObject(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /part-12/src/main/java/com/endoflineblog/truffle/part_12/nodes/exprs/DynamicObjectReferenceExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_12.nodes.exprs; 2 | 3 | import com.oracle.truffle.api.frame.VirtualFrame; 4 | import com.oracle.truffle.api.object.DynamicObject; 5 | 6 | /** 7 | * A simple expression Node that just returns the given {@link DynamicObject}. 8 | * Used for handling methods inside class declarations, 9 | * by passing an instance of {@link com.endoflineblog.truffle.part_12.runtime.ClassPrototypeObject} 10 | * to the constructor of this class, 11 | * and then passing the instance created from that constructor to 12 | * {@link com.endoflineblog.truffle.part_12.nodes.stmts.variables.FuncDeclStmtNode}. 13 | */ 14 | public final class DynamicObjectReferenceExprNode extends EasyScriptExprNode { 15 | private final DynamicObject dynamicObject; 16 | 17 | public DynamicObjectReferenceExprNode(DynamicObject dynamicObject) { 18 | this.dynamicObject = dynamicObject; 19 | } 20 | 21 | @Override 22 | public DynamicObject executeGeneric(VirtualFrame frame) { 23 | return this.dynamicObject; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /part-06/src/main/java/com/endoflineblog/truffle/part_06/nodes/exprs/GlobalVarAssignmentExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_06.nodes.exprs; 2 | 3 | import com.endoflineblog.truffle.part_06.EasyScriptException; 4 | import com.oracle.truffle.api.dsl.NodeChild; 5 | import com.oracle.truffle.api.dsl.NodeField; 6 | import com.oracle.truffle.api.dsl.Specialization; 7 | 8 | /** 9 | * A Node that represents the expression of assigning a value to a global variable in EasyScript. 10 | * Identical to the class with the same name from part 5. 11 | */ 12 | @NodeChild(value = "assignmentExpr") 13 | @NodeField(name = "name", type = String.class) 14 | public abstract class GlobalVarAssignmentExprNode extends EasyScriptExprNode { 15 | protected abstract String getName(); 16 | 17 | @Specialization 18 | protected Object assignVariable(Object value) { 19 | String variableId = this.getName(); 20 | if (!this.currentLanguageContext().globalScopeObject.updateVariable(variableId, value)) { 21 | throw new EasyScriptException(this, "'" + variableId + "' is not defined"); 22 | } 23 | return value; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /part-07/src/main/java/com/endoflineblog/truffle/part_07/nodes/exprs/GlobalVarAssignmentExprNode.java: -------------------------------------------------------------------------------- 1 | package com.endoflineblog.truffle.part_07.nodes.exprs; 2 | 3 | import com.endoflineblog.truffle.part_07.EasyScriptException; 4 | import com.oracle.truffle.api.dsl.NodeChild; 5 | import com.oracle.truffle.api.dsl.NodeField; 6 | import com.oracle.truffle.api.dsl.Specialization; 7 | 8 | /** 9 | * A Node that represents the expression of assigning a value to a global variable in EasyScript. 10 | * Identical to the class with the same name from part 6. 11 | */ 12 | @NodeChild(value = "assignmentExpr") 13 | @NodeField(name = "name", type = String.class) 14 | public abstract class GlobalVarAssignmentExprNode extends EasyScriptExprNode { 15 | protected abstract String getName(); 16 | 17 | @Specialization 18 | protected Object assignVariable(Object value) { 19 | String variableId = this.getName(); 20 | if (!this.currentLanguageContext().globalScopeObject.updateVariable(variableId, value)) { 21 | throw new EasyScriptException(this, "'" + variableId + "' is not defined"); 22 | } 23 | return value; 24 | } 25 | } 26 | --------------------------------------------------------------------------------