├── lib ├── test │ ├── misc │ │ ├── empty_file.lox │ │ ├── unexpected_character.lox │ │ └── precedence.lox │ ├── comments │ │ ├── only_line_comment.lox │ │ ├── only_line_comment_and_line.lox │ │ ├── line_at_eof.lox │ │ └── unicode.lox │ ├── nil │ │ └── literal.lox │ ├── class │ │ ├── empty.lox │ │ ├── inherit_self.lox │ │ ├── local_inherit_other.lox │ │ ├── reference_self.lox │ │ ├── local_inherit_self.lox │ │ ├── local_reference_self.lox │ │ └── inherited_method.lox │ ├── function │ │ ├── empty_body.lox │ │ ├── print.lox │ │ ├── missing_arguments.lox │ │ ├── body_must_be_block.lox │ │ ├── recursion.lox │ │ ├── extra_arguments.lox │ │ ├── missing_comma_in_parameters.lox │ │ ├── local_recursion.lox │ │ ├── mutual_recursion.lox │ │ ├── local_mutual_recursion.lox │ │ ├── parameters.lox │ │ ├── too_many_parameters.lox │ │ └── too_many_arguments.lox │ ├── variable │ │ ├── uninitialized.lox │ │ ├── redeclare_global.lox │ │ ├── redefine_global.lox │ │ ├── use_nil_as_var.lox │ │ ├── use_this_as_var.lox │ │ ├── use_false_as_var.lox │ │ ├── undefined_global.lox │ │ ├── use_global_in_initializer.lox │ │ ├── in_nested_block.lox │ │ ├── unreached_undefined.lox │ │ ├── undefined_local.lox │ │ ├── collide_with_parameter.lox │ │ ├── shadow_global.lox │ │ ├── duplicate_local.lox │ │ ├── duplicate_parameter.lox │ │ ├── use_local_in_initializer.lox │ │ ├── shadow_and_local.lox │ │ ├── shadow_local.lox │ │ ├── local_from_method.lox │ │ ├── early_bound.lox │ │ ├── scope_reuse_in_different_blocks.lox │ │ └── in_middle_of_block.lox │ ├── number │ │ ├── leading_dot.lox │ │ ├── decimal_point_at_eof.lox │ │ ├── trailing_dot.lox │ │ ├── literals.lox │ │ └── nan_equality.lox │ ├── call │ │ ├── nil.lox │ │ ├── num.lox │ │ ├── bool.lox │ │ ├── string.lox │ │ └── object.lox │ ├── if │ │ ├── var_in_then.lox │ │ ├── fun_in_then.lox │ │ ├── class_in_then.lox │ │ ├── fun_in_else.lox │ │ ├── var_in_else.lox │ │ ├── class_in_else.lox │ │ ├── dangling_else.lox │ │ ├── else.lox │ │ ├── truth.lox │ │ └── if.lox │ ├── print │ │ └── missing_argument.lox │ ├── field │ │ ├── get_on_nil.lox │ │ ├── get_on_num.lox │ │ ├── get_on_bool.lox │ │ ├── get_on_string.lox │ │ ├── set_on_nil.lox │ │ ├── set_on_num.lox │ │ ├── set_on_bool.lox │ │ ├── set_on_string.lox │ │ ├── get_on_class.lox │ │ ├── set_on_class.lox │ │ ├── get_on_function.lox │ │ ├── set_evaluation_order.lox │ │ ├── set_on_function.lox │ │ ├── undefined.lox │ │ ├── call_nonfunction_field.lox │ │ ├── method.lox │ │ ├── call_function_field.lox │ │ ├── on_instance.lox │ │ ├── method_binds_this.lox │ │ └── get_and_set_method.lox │ ├── for │ │ ├── fun_in_body.lox │ │ ├── var_in_body.lox │ │ ├── class_in_body.lox │ │ ├── statement_increment.lox │ │ ├── return_inside.lox │ │ ├── statement_initializer.lox │ │ ├── statement_condition.lox │ │ ├── return_closure.lox │ │ ├── closure_in_body.lox │ │ ├── scope.lox │ │ └── syntax.lox │ ├── operator │ │ ├── negate_nonnum.lox │ │ ├── divide_nonnum_num.lox │ │ ├── divide_num_nonnum.lox │ │ ├── multiply_nonnum_num.lox │ │ ├── multiply_num_nonnum.lox │ │ ├── subtract.lox │ │ ├── subtract_nonnum_num.lox │ │ ├── subtract_num_nonnum.lox │ │ ├── multiply.lox │ │ ├── add.lox │ │ ├── divide.lox │ │ ├── greater_nonnum_num.lox │ │ ├── greater_num_nonnum.lox │ │ ├── less_nonnum_num.lox │ │ ├── less_num_nonnum.lox │ │ ├── add_nil_nil.lox │ │ ├── add_num_nil.lox │ │ ├── add_bool_nil.lox │ │ ├── add_bool_num.lox │ │ ├── greater_or_equal_nonnum_num.lox │ │ ├── greater_or_equal_num_nonnum.lox │ │ ├── less_or_equal_nonnum_num.lox │ │ ├── less_or_equal_num_nonnum.lox │ │ ├── negate.lox │ │ ├── not_class.lox │ │ ├── equals_method.lox │ │ ├── not.lox │ │ ├── equals.lox │ │ ├── equals_class.lox │ │ ├── not_equals.lox │ │ └── comparison.lox │ ├── assignment │ │ ├── undefined.lox │ │ ├── grouping.lox │ │ ├── prefix_operator.lox │ │ ├── infix_operator.lox │ │ ├── to_this.lox │ │ ├── syntax.lox │ │ ├── global.lox │ │ ├── associativity.lox │ │ └── local.lox │ ├── this │ │ ├── this_at_top_level.lox │ │ ├── this_in_top_level_function.lox │ │ ├── this_in_method.lox │ │ ├── closure.lox │ │ ├── nested_closure.lox │ │ └── nested_class.lox │ ├── while │ │ ├── fun_in_body.lox │ │ ├── var_in_body.lox │ │ ├── class_in_body.lox │ │ ├── return_inside.lox │ │ ├── return_closure.lox │ │ ├── closure_in_body.lox │ │ └── syntax.lox │ ├── regression │ │ ├── 394.lox │ │ └── 40.lox │ ├── method │ │ ├── empty_block.lox │ │ ├── not_found.lox │ │ ├── print_bound_method.lox │ │ ├── missing_arguments.lox │ │ ├── refer_to_name.lox │ │ ├── extra_arguments.lox │ │ ├── arity.lox │ │ ├── too_many_parameters.lox │ │ └── too_many_arguments.lox │ ├── return │ │ ├── after_if.lox │ │ ├── after_while.lox │ │ ├── in_function.lox │ │ ├── after_else.lox │ │ ├── return_nil_if_no_value.lox │ │ └── in_method.lox │ ├── constructor │ ├── string │ │ ├── multiline.lox │ │ ├── literals.lox │ │ └── error_after_multiline.lox │ ├── bool │ │ ├── not.lox │ │ └── equality.lox │ ├── inheritance │ │ ├── inherit_from_nil.lox │ │ ├── inherit_from_number.lox │ │ ├── inherit_from_function.lox │ │ ├── parenthesized_superclass.lox │ │ ├── constructor.lox │ │ ├── inherit_methods.lox │ │ └── set_fields_from_base_class.lox │ ├── super │ │ ├── super_in_top_level_function.lox │ │ ├── super_without_dot.lox │ │ ├── super_without_name.lox │ │ ├── super_at_top_level.lox │ │ ├── no_superclass_bind.lox │ │ ├── no_superclass_call.lox │ │ ├── parenthesized.lox │ │ ├── no_superclass_method.lox │ │ ├── missing_arguments.lox │ │ ├── indirectly_inherited.lox │ │ ├── call_same_method.lox │ │ ├── call_other_method.lox │ │ ├── this_in_superclass_method.lox │ │ ├── constructor.lox │ │ ├── super_in_inherited_method.lox │ │ ├── extra_arguments.lox │ │ ├── bound_method.lox │ │ ├── closure.lox │ │ ├── super_in_closure_in_inherited_method.lox │ │ └── reassign_superclass.lox │ ├── block │ │ ├── empty.lox │ │ └── scope.lox │ ├── closure │ │ ├── open_closure_in_function.lox │ │ ├── closed_closure_in_function.lox │ │ ├── close_over_function_parameter.lox │ │ ├── reference_closure_multiple_times.lox │ │ ├── close_over_method_parameter.lox │ │ ├── assign_to_shadowed_later.lox │ │ ├── shadow_closure_with_local.lox │ │ ├── reuse_closure_slot.lox │ │ ├── nested_closure.lox │ │ ├── unused_closure.lox │ │ ├── assign_to_closure.lox │ │ ├── close_over_later_variable.lox │ │ └── unused_later_closure.lox │ └── logical_operator │ │ ├── or_truth.lox │ │ ├── and_truth.lox │ │ ├── and.lox │ │ └── or.lox ├── table.dart ├── error.dart ├── main.dart ├── chunk.dart ├── parser.dart ├── object.dart ├── value.dart ├── native_classes.dart └── test.dart ├── .DS_Store ├── CHANGELOG.md ├── doc └── images │ ├── fib.png │ ├── intro.gif │ ├── bytecode.png │ ├── benchmark.png │ └── vm_output.png ├── editor ├── ios │ ├── Runner │ │ ├── Runner-Bridging-Header.h │ │ ├── Assets.xcassets │ │ │ ├── LaunchImage.imageset │ │ │ │ ├── LaunchImage.png │ │ │ │ ├── LaunchImage@2x.png │ │ │ │ ├── LaunchImage@3x.png │ │ │ │ ├── README.md │ │ │ │ └── Contents.json │ │ │ └── AppIcon.appiconset │ │ │ │ ├── Icon-App-20x20@1x.png │ │ │ │ ├── Icon-App-20x20@2x.png │ │ │ │ ├── Icon-App-20x20@3x.png │ │ │ │ ├── Icon-App-29x29@1x.png │ │ │ │ ├── Icon-App-29x29@2x.png │ │ │ │ ├── Icon-App-29x29@3x.png │ │ │ │ ├── Icon-App-40x40@1x.png │ │ │ │ ├── Icon-App-40x40@2x.png │ │ │ │ ├── Icon-App-40x40@3x.png │ │ │ │ ├── Icon-App-60x60@2x.png │ │ │ │ ├── Icon-App-60x60@3x.png │ │ │ │ ├── Icon-App-76x76@1x.png │ │ │ │ ├── Icon-App-76x76@2x.png │ │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ │ ├── Icon-App-83.5x83.5@2x.png │ │ │ │ └── Contents.json │ │ ├── AppDelegate.swift │ │ ├── Base.lproj │ │ │ ├── Main.storyboard │ │ │ └── LaunchScreen.storyboard │ │ └── Info.plist │ ├── Flutter │ │ ├── Debug.xcconfig │ │ ├── Release.xcconfig │ │ └── AppFrameworkInfo.plist │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ └── IDEWorkspaceChecks.plist │ ├── Runner.xcodeproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ ├── .gitignore │ └── Podfile ├── web │ ├── favicon.png │ ├── icons │ │ ├── Icon-192.png │ │ └── Icon-512.png │ ├── manifest.json │ └── index.html ├── android │ ├── gradle.properties │ ├── app │ │ ├── src │ │ │ ├── main │ │ │ │ ├── res │ │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── drawable │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ ├── values │ │ │ │ │ │ └── styles.xml │ │ │ │ │ └── values-night │ │ │ │ │ │ └── styles.xml │ │ │ │ ├── kotlin │ │ │ │ │ └── com │ │ │ │ │ │ └── example │ │ │ │ │ │ └── demo │ │ │ │ │ │ └── MainActivity.kt │ │ │ │ └── AndroidManifest.xml │ │ │ ├── debug │ │ │ │ └── AndroidManifest.xml │ │ │ └── profile │ │ │ │ └── AndroidManifest.xml │ │ └── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ ├── .gitignore │ ├── settings.gradle │ └── build.gradle ├── assets │ ├── snippets │ │ ├── precedence.lox │ │ ├── closure.lox │ │ ├── fibonacci.lox │ │ ├── benchmark.lox │ │ ├── linked_list.lox │ │ ├── containers.lox │ │ └── inheritance.lox │ └── fonts │ │ └── sourceCode │ │ ├── SourceCodePro-Bold.ttf │ │ ├── SourceCodePro-Black.ttf │ │ ├── SourceCodePro-Italic.ttf │ │ ├── SourceCodePro-Light.ttf │ │ ├── SourceCodePro-Medium.ttf │ │ ├── SourceCodePro-Regular.ttf │ │ ├── SourceCodePro-SemiBold.ttf │ │ ├── SourceCodePro-BlackItalic.ttf │ │ ├── SourceCodePro-BoldItalic.ttf │ │ ├── SourceCodePro-ExtraLight.ttf │ │ ├── SourceCodePro-LightItalic.ttf │ │ ├── SourceCodePro-MediumItalic.ttf │ │ ├── SourceCodePro-SemiBoldItalic.ttf │ │ └── SourceCodePro-ExtraLightItalic.ttf ├── .metadata ├── deploy.sh ├── lib │ ├── constants.dart │ ├── widgets │ │ ├── progress_button.dart │ │ ├── flushbar.dart │ │ ├── toggle_button.dart │ │ └── monitor.dart │ ├── lox_mode.dart │ ├── code_editor.dart │ ├── editor_toolbar.dart │ ├── main.dart │ └── runtime.dart ├── .gitignore └── pubspec.yaml ├── dlox.code-workspace ├── bin └── dlox.dart ├── .gitignore ├── pubspec.yaml ├── analysis_options.yaml ├── LICENSE └── README.md /lib/test/misc/empty_file.lox: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/test/comments/only_line_comment.lox: -------------------------------------------------------------------------------- 1 | // comment -------------------------------------------------------------------------------- /lib/test/nil/literal.lox: -------------------------------------------------------------------------------- 1 | print nil; // expect: nil 2 | -------------------------------------------------------------------------------- /lib/test/comments/only_line_comment_and_line.lox: -------------------------------------------------------------------------------- 1 | // comment 2 | -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BertrandBev/dlox/HEAD/.DS_Store -------------------------------------------------------------------------------- /lib/test/comments/line_at_eof.lox: -------------------------------------------------------------------------------- 1 | print "ok"; // expect: ok 2 | // comment -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 1.0.0 2 | 3 | - Initial version, created by Stagehand 4 | -------------------------------------------------------------------------------- /lib/test/class/empty.lox: -------------------------------------------------------------------------------- 1 | class Foo {} 2 | 3 | print Foo; // expect: Foo 4 | -------------------------------------------------------------------------------- /lib/test/function/empty_body.lox: -------------------------------------------------------------------------------- 1 | fun f() {} 2 | print f(); // expect: nil 3 | -------------------------------------------------------------------------------- /lib/test/variable/uninitialized.lox: -------------------------------------------------------------------------------- 1 | var a; 2 | print a; // expect: nil 3 | -------------------------------------------------------------------------------- /lib/test/function/print.lox: -------------------------------------------------------------------------------- 1 | fun foo() {} 2 | print foo; // expect: 3 | -------------------------------------------------------------------------------- /lib/test/number/leading_dot.lox: -------------------------------------------------------------------------------- 1 | .123; // Error at '.': Expect expression. 2 | 3 | -------------------------------------------------------------------------------- /doc/images/fib.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BertrandBev/dlox/HEAD/doc/images/fib.png -------------------------------------------------------------------------------- /editor/ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /lib/test/call/nil.lox: -------------------------------------------------------------------------------- 1 | nil(); // Runtime error: Can only call functions and classes. 2 | -------------------------------------------------------------------------------- /lib/test/call/num.lox: -------------------------------------------------------------------------------- 1 | 123(); // Runtime error: Can only call functions and classes. 2 | -------------------------------------------------------------------------------- /lib/test/if/var_in_then.lox: -------------------------------------------------------------------------------- 1 | if (true) var foo; // Error at 'var': Expect expression. 2 | -------------------------------------------------------------------------------- /lib/test/print/missing_argument.lox: -------------------------------------------------------------------------------- 1 | print; // Error at ';': Expect expression. 2 | 3 | -------------------------------------------------------------------------------- /doc/images/intro.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BertrandBev/dlox/HEAD/doc/images/intro.gif -------------------------------------------------------------------------------- /lib/test/call/bool.lox: -------------------------------------------------------------------------------- 1 | true(); // Runtime error: Can only call functions and classes. 2 | -------------------------------------------------------------------------------- /lib/test/call/string.lox: -------------------------------------------------------------------------------- 1 | "str"(); // Runtime error: Can only call functions and classes. 2 | -------------------------------------------------------------------------------- /lib/test/field/get_on_nil.lox: -------------------------------------------------------------------------------- 1 | nil.foo; // Runtime error: Only instances have properties. 2 | -------------------------------------------------------------------------------- /lib/test/field/get_on_num.lox: -------------------------------------------------------------------------------- 1 | 123.foo; // Runtime error: Only instances have properties. 2 | -------------------------------------------------------------------------------- /lib/test/for/fun_in_body.lox: -------------------------------------------------------------------------------- 1 | for (;;) fun foo() {} // Error at 'fun': Expect expression. 2 | -------------------------------------------------------------------------------- /lib/test/for/var_in_body.lox: -------------------------------------------------------------------------------- 1 | for (;;) var foo; // Error at 'var': Expect expression. 2 | 3 | -------------------------------------------------------------------------------- /lib/test/operator/negate_nonnum.lox: -------------------------------------------------------------------------------- 1 | -"s"; // Runtime error: Operand must be a number. 2 | -------------------------------------------------------------------------------- /doc/images/bytecode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BertrandBev/dlox/HEAD/doc/images/bytecode.png -------------------------------------------------------------------------------- /editor/web/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BertrandBev/dlox/HEAD/editor/web/favicon.png -------------------------------------------------------------------------------- /lib/test/field/get_on_bool.lox: -------------------------------------------------------------------------------- 1 | true.foo; // Runtime error: Only instances have properties. 2 | -------------------------------------------------------------------------------- /lib/test/field/get_on_string.lox: -------------------------------------------------------------------------------- 1 | "str".foo; // Runtime error: Only instances have properties. 2 | -------------------------------------------------------------------------------- /lib/test/field/set_on_nil.lox: -------------------------------------------------------------------------------- 1 | nil.foo = "value"; // Runtime error: Only instances have fields. 2 | -------------------------------------------------------------------------------- /lib/test/field/set_on_num.lox: -------------------------------------------------------------------------------- 1 | 123.foo = "value"; // Runtime error: Only instances have fields. 2 | -------------------------------------------------------------------------------- /lib/test/for/class_in_body.lox: -------------------------------------------------------------------------------- 1 | for (;;) class Foo {} // Error at 'class': Expect expression. 2 | -------------------------------------------------------------------------------- /lib/test/if/fun_in_then.lox: -------------------------------------------------------------------------------- 1 | if (true) fun foo() {} // Error at 'fun': Expect expression. 2 | 3 | -------------------------------------------------------------------------------- /lib/test/number/decimal_point_at_eof.lox: -------------------------------------------------------------------------------- 1 | 123. 2 | // Error at end: Expect property name after '.'. -------------------------------------------------------------------------------- /lib/test/number/trailing_dot.lox: -------------------------------------------------------------------------------- 1 | 123.; // Error at ';': Expect property name after '.'. 2 | 3 | -------------------------------------------------------------------------------- /lib/test/operator/divide_nonnum_num.lox: -------------------------------------------------------------------------------- 1 | "1" / 1; // Runtime error: Operands must be numbers. 2 | -------------------------------------------------------------------------------- /lib/test/operator/divide_num_nonnum.lox: -------------------------------------------------------------------------------- 1 | 1 / "1"; // Runtime error: Operands must be numbers. 2 | -------------------------------------------------------------------------------- /lib/test/operator/multiply_nonnum_num.lox: -------------------------------------------------------------------------------- 1 | "1" * 1; // Runtime error: Operands must be numbers. 2 | -------------------------------------------------------------------------------- /lib/test/operator/multiply_num_nonnum.lox: -------------------------------------------------------------------------------- 1 | 1 * "1"; // Runtime error: Operands must be numbers. 2 | -------------------------------------------------------------------------------- /lib/test/operator/subtract.lox: -------------------------------------------------------------------------------- 1 | print 4 - 3; // expect: 1 2 | print 1.2 - 1.2; // expect: 0 3 | -------------------------------------------------------------------------------- /lib/test/operator/subtract_nonnum_num.lox: -------------------------------------------------------------------------------- 1 | "1" - 1; // Runtime error: Operands must be numbers. 2 | -------------------------------------------------------------------------------- /lib/test/operator/subtract_num_nonnum.lox: -------------------------------------------------------------------------------- 1 | 1 - "1"; // Runtime error: Operands must be numbers. 2 | -------------------------------------------------------------------------------- /lib/test/variable/redeclare_global.lox: -------------------------------------------------------------------------------- 1 | var a = "1"; 2 | var a; 3 | print a; // expect: nil 4 | -------------------------------------------------------------------------------- /lib/test/variable/redefine_global.lox: -------------------------------------------------------------------------------- 1 | var a = "1"; 2 | var a = "2"; 3 | print a; // expect: 2 4 | -------------------------------------------------------------------------------- /lib/test/variable/use_nil_as_var.lox: -------------------------------------------------------------------------------- 1 | var nil = "value"; // Error at 'nil': Expect variable name. -------------------------------------------------------------------------------- /lib/test/variable/use_this_as_var.lox: -------------------------------------------------------------------------------- 1 | var this = "value"; // Error at 'this': Expect variable name. -------------------------------------------------------------------------------- /doc/images/benchmark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BertrandBev/dlox/HEAD/doc/images/benchmark.png -------------------------------------------------------------------------------- /doc/images/vm_output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BertrandBev/dlox/HEAD/doc/images/vm_output.png -------------------------------------------------------------------------------- /lib/test/assignment/undefined.lox: -------------------------------------------------------------------------------- 1 | unknown = "what"; // Runtime error: Undefined variable 'unknown'. 2 | -------------------------------------------------------------------------------- /lib/test/field/set_on_bool.lox: -------------------------------------------------------------------------------- 1 | true.foo = "value"; // Runtime error: Only instances have fields. 2 | -------------------------------------------------------------------------------- /lib/test/field/set_on_string.lox: -------------------------------------------------------------------------------- 1 | "str".foo = "value"; // Runtime error: Only instances have fields. 2 | -------------------------------------------------------------------------------- /lib/test/if/class_in_then.lox: -------------------------------------------------------------------------------- 1 | if (true) class Foo {} // Error at 'class': Expect expression. 2 | 3 | -------------------------------------------------------------------------------- /lib/test/misc/unexpected_character.lox: -------------------------------------------------------------------------------- 1 | foo(a or b); // Runtime error: Undefined variable 'foo'. 2 | -------------------------------------------------------------------------------- /lib/test/operator/multiply.lox: -------------------------------------------------------------------------------- 1 | print 5 * 3; // expect: 15 2 | print 12.34 * 0.3; // expect: 3.702 3 | -------------------------------------------------------------------------------- /lib/test/this/this_at_top_level.lox: -------------------------------------------------------------------------------- 1 | this; // Error at 'this': Can't use 'this' outside of a class. 2 | -------------------------------------------------------------------------------- /lib/test/while/fun_in_body.lox: -------------------------------------------------------------------------------- 1 | while (true) fun foo() {} // Error at 'fun': Expect expression. 2 | 3 | -------------------------------------------------------------------------------- /lib/test/while/var_in_body.lox: -------------------------------------------------------------------------------- 1 | while (true) var foo; // Error at 'var': Expect expression. 2 | 3 | -------------------------------------------------------------------------------- /dlox.code-workspace: -------------------------------------------------------------------------------- 1 | { 2 | "folders": [ 3 | { 4 | "path": "." 5 | } 6 | ], 7 | "settings": {} 8 | } -------------------------------------------------------------------------------- /lib/test/class/inherit_self.lox: -------------------------------------------------------------------------------- 1 | class Foo < Foo {} // Error at 'Foo': A class can't inherit from itself. 2 | -------------------------------------------------------------------------------- /lib/test/if/fun_in_else.lox: -------------------------------------------------------------------------------- 1 | if (true) "ok"; else fun foo() {} // Error at 'fun': Expect expression. 2 | 3 | -------------------------------------------------------------------------------- /lib/test/if/var_in_else.lox: -------------------------------------------------------------------------------- 1 | if (true) "ok"; else var foo; // Error at 'var': Expect expression. 2 | 3 | -------------------------------------------------------------------------------- /lib/test/operator/add.lox: -------------------------------------------------------------------------------- 1 | print 123 + 456; // expect: 579 2 | print "str" + "ing"; // expect: string 3 | -------------------------------------------------------------------------------- /lib/test/operator/divide.lox: -------------------------------------------------------------------------------- 1 | print 8 / 2; // expect: 4 2 | print 12.34 / 12.34; // expect: 1 3 | -------------------------------------------------------------------------------- /lib/test/operator/greater_nonnum_num.lox: -------------------------------------------------------------------------------- 1 | "1" > 1; // Runtime error: Operands must be numbers or strings. 2 | -------------------------------------------------------------------------------- /lib/test/operator/greater_num_nonnum.lox: -------------------------------------------------------------------------------- 1 | 1 > "1"; // Runtime error: Operands must be numbers or strings. 2 | -------------------------------------------------------------------------------- /lib/test/operator/less_nonnum_num.lox: -------------------------------------------------------------------------------- 1 | "1" < 1; // Runtime error: Operands must be numbers or strings. 2 | -------------------------------------------------------------------------------- /lib/test/operator/less_num_nonnum.lox: -------------------------------------------------------------------------------- 1 | 1 < "1"; // Runtime error: Operands must be numbers or strings. 2 | -------------------------------------------------------------------------------- /lib/test/regression/394.lox: -------------------------------------------------------------------------------- 1 | { 2 | class A {} 3 | class B < A {} 4 | print B; // expect: B 5 | } 6 | -------------------------------------------------------------------------------- /lib/test/variable/use_false_as_var.lox: -------------------------------------------------------------------------------- 1 | var false = "value"; // Error at 'false': Expect variable name. 2 | -------------------------------------------------------------------------------- /lib/test/while/class_in_body.lox: -------------------------------------------------------------------------------- 1 | while (true) class Foo {} // Error at 'class': Expect expression. 2 | 3 | -------------------------------------------------------------------------------- /editor/web/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BertrandBev/dlox/HEAD/editor/web/icons/Icon-192.png -------------------------------------------------------------------------------- /editor/web/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BertrandBev/dlox/HEAD/editor/web/icons/Icon-512.png -------------------------------------------------------------------------------- /lib/test/assignment/grouping.lox: -------------------------------------------------------------------------------- 1 | var a = "a"; 2 | (a) = "value"; // Error at '=': Invalid assignment target. 3 | -------------------------------------------------------------------------------- /lib/test/field/get_on_class.lox: -------------------------------------------------------------------------------- 1 | class Foo {} 2 | Foo.bar; // Runtime error: Only instances have properties. 3 | -------------------------------------------------------------------------------- /lib/test/if/class_in_else.lox: -------------------------------------------------------------------------------- 1 | if (true) "ok"; else class Foo {} // Error at 'class': Expect expression. 2 | 3 | -------------------------------------------------------------------------------- /lib/test/method/empty_block.lox: -------------------------------------------------------------------------------- 1 | class Foo { 2 | bar() {} 3 | } 4 | 5 | print Foo().bar(); // expect: nil 6 | -------------------------------------------------------------------------------- /lib/test/operator/add_nil_nil.lox: -------------------------------------------------------------------------------- 1 | nil + nil; // Runtime error: Operands must numbers, strings, lists or maps. 2 | -------------------------------------------------------------------------------- /lib/test/operator/add_num_nil.lox: -------------------------------------------------------------------------------- 1 | 1 + nil; // Runtime error: Operands must numbers, strings, lists or maps. 2 | -------------------------------------------------------------------------------- /lib/test/return/after_if.lox: -------------------------------------------------------------------------------- 1 | fun f() { 2 | if (true) return "ok"; 3 | } 4 | 5 | print f(); // expect: ok 6 | -------------------------------------------------------------------------------- /lib/test/variable/undefined_global.lox: -------------------------------------------------------------------------------- 1 | print notDefined; // Runtime error: Undefined variable 'notDefined'. 2 | -------------------------------------------------------------------------------- /lib/test/variable/use_global_in_initializer.lox: -------------------------------------------------------------------------------- 1 | var a = "value"; 2 | var a = a; 3 | print a; // expect: value 4 | -------------------------------------------------------------------------------- /lib/test/assignment/prefix_operator.lox: -------------------------------------------------------------------------------- 1 | var a = "a"; 2 | !a = "value"; // Error at '=': Invalid assignment target. 3 | -------------------------------------------------------------------------------- /lib/test/constructor/default.lox: -------------------------------------------------------------------------------- 1 | class Foo {} 2 | 3 | var foo = Foo(); 4 | print foo; // expect: Foo instance 5 | -------------------------------------------------------------------------------- /lib/test/field/set_on_class.lox: -------------------------------------------------------------------------------- 1 | class Foo {} 2 | Foo.bar = "value"; // Runtime error: Only instances have fields. 3 | -------------------------------------------------------------------------------- /lib/test/operator/add_bool_nil.lox: -------------------------------------------------------------------------------- 1 | true + nil; // Runtime error: Operands must numbers, strings, lists or maps. 2 | -------------------------------------------------------------------------------- /lib/test/operator/add_bool_num.lox: -------------------------------------------------------------------------------- 1 | true + 123; // Runtime error: Operands must numbers, strings, lists or maps. 2 | -------------------------------------------------------------------------------- /lib/test/operator/greater_or_equal_nonnum_num.lox: -------------------------------------------------------------------------------- 1 | "1" >= 1; // Runtime error: Operands must be numbers or strings. 2 | -------------------------------------------------------------------------------- /lib/test/operator/greater_or_equal_num_nonnum.lox: -------------------------------------------------------------------------------- 1 | 1 >= "1"; // Runtime error: Operands must be numbers or strings. 2 | -------------------------------------------------------------------------------- /lib/test/operator/less_or_equal_nonnum_num.lox: -------------------------------------------------------------------------------- 1 | "1" <= 1; // Runtime error: Operands must be numbers or strings. 2 | -------------------------------------------------------------------------------- /lib/test/operator/less_or_equal_num_nonnum.lox: -------------------------------------------------------------------------------- 1 | 1 <= "1"; // Runtime error: Operands must be numbers or strings. 2 | -------------------------------------------------------------------------------- /lib/test/return/after_while.lox: -------------------------------------------------------------------------------- 1 | fun f() { 2 | while (true) return "ok"; 3 | } 4 | 5 | print f(); // expect: ok 6 | -------------------------------------------------------------------------------- /lib/test/variable/in_nested_block.lox: -------------------------------------------------------------------------------- 1 | { 2 | var a = "outer"; 3 | { 4 | print a; // expect: outer 5 | } 6 | } -------------------------------------------------------------------------------- /lib/test/field/get_on_function.lox: -------------------------------------------------------------------------------- 1 | fun foo() {} 2 | 3 | foo.bar; // Runtime error: Only instances have properties. 4 | -------------------------------------------------------------------------------- /lib/test/function/missing_arguments.lox: -------------------------------------------------------------------------------- 1 | fun f(a, b) {} 2 | 3 | f(1); // Runtime error: Expected 2 arguments but got 1. 4 | -------------------------------------------------------------------------------- /lib/test/method/not_found.lox: -------------------------------------------------------------------------------- 1 | class Foo {} 2 | 3 | Foo().unknown(); // Runtime error: Undefined property 'unknown'. 4 | -------------------------------------------------------------------------------- /lib/test/operator/negate.lox: -------------------------------------------------------------------------------- 1 | print -(3); // expect: -3 2 | print --(3); // expect: 3 3 | print ---(3); // expect: -3 4 | -------------------------------------------------------------------------------- /lib/test/return/in_function.lox: -------------------------------------------------------------------------------- 1 | fun f() { 2 | return "ok"; 3 | print "bad"; 4 | } 5 | 6 | print f(); // expect: ok 7 | -------------------------------------------------------------------------------- /lib/test/string/multiline.lox: -------------------------------------------------------------------------------- 1 | var a = "1 2 | 2 3 | 3"; 4 | print a; 5 | // expect: 1 6 | // expect: 2 7 | // expect: 3 8 | -------------------------------------------------------------------------------- /lib/test/variable/unreached_undefined.lox: -------------------------------------------------------------------------------- 1 | if (false) { 2 | print notDefined; 3 | } 4 | 5 | print "ok"; // expect: ok 6 | -------------------------------------------------------------------------------- /lib/test/field/set_evaluation_order.lox: -------------------------------------------------------------------------------- 1 | undefined1.bar // Runtime error: Undefined variable 'undefined1'. 2 | = undefined2; -------------------------------------------------------------------------------- /lib/test/field/set_on_function.lox: -------------------------------------------------------------------------------- 1 | fun foo() {} 2 | 3 | foo.bar = "value"; // Runtime error: Only instances have fields. 4 | -------------------------------------------------------------------------------- /lib/test/field/undefined.lox: -------------------------------------------------------------------------------- 1 | class Foo {} 2 | var foo = Foo(); 3 | 4 | foo.bar; // Runtime error: Undefined property 'bar'. 5 | -------------------------------------------------------------------------------- /lib/test/for/statement_increment.lox: -------------------------------------------------------------------------------- 1 | 2 | // for (var a = 1; a < 2; {}) {} // [disabled] Error at '{': Expect expression. 3 | -------------------------------------------------------------------------------- /lib/test/operator/not_class.lox: -------------------------------------------------------------------------------- 1 | class Bar {} 2 | print !Bar; // expect: false 3 | print !Bar(); // expect: false 4 | -------------------------------------------------------------------------------- /lib/test/return/after_else.lox: -------------------------------------------------------------------------------- 1 | fun f() { 2 | if (false) "no"; else return "ok"; 3 | } 4 | 5 | print f(); // expect: ok 6 | -------------------------------------------------------------------------------- /lib/test/variable/undefined_local.lox: -------------------------------------------------------------------------------- 1 | { 2 | print notDefined; // Runtime error: Undefined variable 'notDefined'. 3 | } 4 | -------------------------------------------------------------------------------- /lib/test/bool/not.lox: -------------------------------------------------------------------------------- 1 | print !true; // expect: false 2 | print !false; // expect: true 3 | print !!true; // expect: true 4 | -------------------------------------------------------------------------------- /lib/test/call/object.lox: -------------------------------------------------------------------------------- 1 | class Foo {} 2 | 3 | var foo = Foo(); 4 | foo(); // Runtime error: Can only call functions and classes. 5 | -------------------------------------------------------------------------------- /lib/test/function/body_must_be_block.lox: -------------------------------------------------------------------------------- 1 | fun f() 123; // Error at '123': Expect function body. 2 | // Error at end: Unterminated block -------------------------------------------------------------------------------- /lib/test/inheritance/inherit_from_nil.lox: -------------------------------------------------------------------------------- 1 | var Nil = nil; 2 | class Foo < Nil {} // Runtime error: Superclass must be a class. 3 | -------------------------------------------------------------------------------- /lib/test/return/return_nil_if_no_value.lox: -------------------------------------------------------------------------------- 1 | fun f() { 2 | return; 3 | print "bad"; 4 | } 5 | 6 | print f(); // expect: nil 7 | -------------------------------------------------------------------------------- /lib/test/assignment/infix_operator.lox: -------------------------------------------------------------------------------- 1 | var a = "a"; 2 | var b = "b"; 3 | a + b = "value"; // Error at '=': Invalid assignment target. 4 | -------------------------------------------------------------------------------- /lib/test/inheritance/inherit_from_number.lox: -------------------------------------------------------------------------------- 1 | var Number = 123; 2 | class Foo < Number {} // Runtime error: Superclass must be a class. 3 | -------------------------------------------------------------------------------- /lib/test/this/this_in_top_level_function.lox: -------------------------------------------------------------------------------- 1 | fun foo() { 2 | this; // Error at 'this': Can't use 'this' outside of a class. 3 | } 4 | -------------------------------------------------------------------------------- /bin/dlox.dart: -------------------------------------------------------------------------------- 1 | import 'package:dlox/main.dart' as shell; 2 | 3 | void main(List arguments) { 4 | shell.main(arguments); 5 | } 6 | -------------------------------------------------------------------------------- /lib/test/constructor/default_arguments.lox: -------------------------------------------------------------------------------- 1 | class Foo {} 2 | 3 | var foo = Foo(1, 2, 3); // Runtime error: Expected 0 arguments but got 3. 4 | -------------------------------------------------------------------------------- /lib/test/inheritance/inherit_from_function.lox: -------------------------------------------------------------------------------- 1 | fun foo() {} 2 | 3 | class Subclass < foo {} // Runtime error: Superclass must be a class. 4 | -------------------------------------------------------------------------------- /lib/test/inheritance/parenthesized_superclass.lox: -------------------------------------------------------------------------------- 1 | class Foo {} 2 | 3 | class Bar < (Foo) {} // Error at '(': Expect superclass name. 4 | 5 | -------------------------------------------------------------------------------- /lib/test/super/super_in_top_level_function.lox: -------------------------------------------------------------------------------- 1 | super.bar(); // Error at 'super': Can't use 'super' outside of a class. 2 | fun foo() { 3 | } -------------------------------------------------------------------------------- /editor/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /lib/test/class/local_inherit_other.lox: -------------------------------------------------------------------------------- 1 | class A {} 2 | 3 | fun f() { 4 | class B < A {} 5 | return B; 6 | } 7 | 8 | print f(); // expect: B 9 | -------------------------------------------------------------------------------- /lib/test/method/print_bound_method.lox: -------------------------------------------------------------------------------- 1 | class Foo { 2 | method() { } 3 | } 4 | var foo = Foo(); 5 | print foo.method; // expect: 6 | -------------------------------------------------------------------------------- /lib/test/variable/collide_with_parameter.lox: -------------------------------------------------------------------------------- 1 | fun foo(a) { 2 | var a; // Error at 'a': Already variable with this name in this scope. 3 | } 4 | -------------------------------------------------------------------------------- /editor/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | android.enableR8=true 5 | -------------------------------------------------------------------------------- /editor/assets/snippets/precedence.lox: -------------------------------------------------------------------------------- 1 | // Simple example to show how the precedence is handled 2 | // by the stack model 3 | print 3 * (1 + 2) + 8 / 4 + 1; -------------------------------------------------------------------------------- /editor/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /lib/test/block/empty.lox: -------------------------------------------------------------------------------- 1 | {} // By itself. 2 | 3 | // In a statement. 4 | if (true) {} 5 | if (false) {} else {} 6 | 7 | print "ok"; // expect: ok 8 | -------------------------------------------------------------------------------- /lib/test/block/scope.lox: -------------------------------------------------------------------------------- 1 | var a = "outer"; 2 | 3 | { 4 | var a = "inner"; 5 | print a; // expect: inner 6 | } 7 | 8 | print a; // expect: outer 9 | -------------------------------------------------------------------------------- /editor/assets/fonts/sourceCode/SourceCodePro-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BertrandBev/dlox/HEAD/editor/assets/fonts/sourceCode/SourceCodePro-Bold.ttf -------------------------------------------------------------------------------- /lib/test/class/reference_self.lox: -------------------------------------------------------------------------------- 1 | class Foo { 2 | returnSelf() { 3 | return Foo; 4 | } 5 | } 6 | 7 | print Foo().returnSelf(); // expect: Foo 8 | -------------------------------------------------------------------------------- /lib/test/closure/open_closure_in_function.lox: -------------------------------------------------------------------------------- 1 | { 2 | var local = "local"; 3 | fun f() { 4 | print local; // expect: local 5 | } 6 | f(); 7 | } 8 | -------------------------------------------------------------------------------- /lib/test/function/recursion.lox: -------------------------------------------------------------------------------- 1 | fun fib(n) { 2 | if (n < 2) return n; 3 | return fib(n - 1) + fib(n - 2); 4 | } 5 | 6 | print fib(8); // expect: 21 7 | -------------------------------------------------------------------------------- /lib/test/method/missing_arguments.lox: -------------------------------------------------------------------------------- 1 | class Foo { 2 | method(a, b) {} 3 | } 4 | 5 | Foo().method(1); // Runtime error: Expected 2 arguments but got 1. 6 | -------------------------------------------------------------------------------- /lib/test/variable/shadow_global.lox: -------------------------------------------------------------------------------- 1 | var a = "global"; 2 | { 3 | var a = "shadow"; 4 | print a; // expect: shadow 5 | } 6 | print a; // expect: global 7 | -------------------------------------------------------------------------------- /editor/assets/fonts/sourceCode/SourceCodePro-Black.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BertrandBev/dlox/HEAD/editor/assets/fonts/sourceCode/SourceCodePro-Black.ttf -------------------------------------------------------------------------------- /editor/assets/fonts/sourceCode/SourceCodePro-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BertrandBev/dlox/HEAD/editor/assets/fonts/sourceCode/SourceCodePro-Italic.ttf -------------------------------------------------------------------------------- /editor/assets/fonts/sourceCode/SourceCodePro-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BertrandBev/dlox/HEAD/editor/assets/fonts/sourceCode/SourceCodePro-Light.ttf -------------------------------------------------------------------------------- /editor/assets/fonts/sourceCode/SourceCodePro-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BertrandBev/dlox/HEAD/editor/assets/fonts/sourceCode/SourceCodePro-Medium.ttf -------------------------------------------------------------------------------- /lib/test/assignment/to_this.lox: -------------------------------------------------------------------------------- 1 | class Foo { 2 | Foo() { 3 | this = "value"; // Error at '=': Invalid assignment target. 4 | } 5 | } 6 | 7 | Foo(); 8 | -------------------------------------------------------------------------------- /lib/test/constructor/missing_arguments.lox: -------------------------------------------------------------------------------- 1 | class Foo { 2 | init(a, b) {} 3 | } 4 | 5 | var foo = Foo(1); // Runtime error: Expected 2 arguments but got 1. 6 | -------------------------------------------------------------------------------- /lib/test/for/return_inside.lox: -------------------------------------------------------------------------------- 1 | fun f() { 2 | for (;;) { 3 | var i = "i"; 4 | return i; 5 | } 6 | } 7 | 8 | print f(); 9 | // expect: i 10 | -------------------------------------------------------------------------------- /lib/test/return/in_method.lox: -------------------------------------------------------------------------------- 1 | class Foo { 2 | method() { 3 | return "ok"; 4 | print "bad"; 5 | } 6 | } 7 | 8 | print Foo().method(); // expect: ok 9 | -------------------------------------------------------------------------------- /lib/test/super/super_without_dot.lox: -------------------------------------------------------------------------------- 1 | class A {} 2 | 3 | class B < A { 4 | method() { 5 | super; // Error at ';': Expect '.' after 'super'. 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /lib/test/this/this_in_method.lox: -------------------------------------------------------------------------------- 1 | class Foo { 2 | bar() { return this; } 3 | baz() { return "baz"; } 4 | } 5 | 6 | print Foo().bar().baz(); // expect: baz 7 | -------------------------------------------------------------------------------- /lib/test/variable/duplicate_local.lox: -------------------------------------------------------------------------------- 1 | { 2 | var a = "value"; 3 | var a = "other"; // Error at 'a': Already variable with this name in this scope. 4 | } 5 | -------------------------------------------------------------------------------- /lib/test/variable/duplicate_parameter.lox: -------------------------------------------------------------------------------- 1 | fun foo(arg, 2 | arg) { // Error at 'arg': Already variable with this name in this scope. 3 | "body"; 4 | } 5 | -------------------------------------------------------------------------------- /lib/test/variable/use_local_in_initializer.lox: -------------------------------------------------------------------------------- 1 | var a = "outer"; 2 | { 3 | var a = a; // Error at 'a': Can't read local variable in its own initializer. 4 | } 5 | -------------------------------------------------------------------------------- /editor/assets/fonts/sourceCode/SourceCodePro-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BertrandBev/dlox/HEAD/editor/assets/fonts/sourceCode/SourceCodePro-Regular.ttf -------------------------------------------------------------------------------- /editor/assets/fonts/sourceCode/SourceCodePro-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BertrandBev/dlox/HEAD/editor/assets/fonts/sourceCode/SourceCodePro-SemiBold.ttf -------------------------------------------------------------------------------- /lib/test/function/extra_arguments.lox: -------------------------------------------------------------------------------- 1 | fun f(a, b) { 2 | print a; 3 | print b; 4 | } 5 | 6 | f(1, 2, 3, 4); // Runtime error: Expected 2 arguments but got 4. 7 | -------------------------------------------------------------------------------- /lib/test/function/missing_comma_in_parameters.lox: -------------------------------------------------------------------------------- 1 | fun foo(a, b c, d, e, f) // Error at 'c': Expect ')' after parameters. 2 | {} 3 | // Error at end: Unterminated block. -------------------------------------------------------------------------------- /lib/test/while/return_inside.lox: -------------------------------------------------------------------------------- 1 | fun f() { 2 | while (true) { 3 | var i = "i"; 4 | return i; 5 | } 6 | } 7 | 8 | print f(); 9 | // expect: i 10 | -------------------------------------------------------------------------------- /editor/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BertrandBev/dlox/HEAD/editor/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /editor/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BertrandBev/dlox/HEAD/editor/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /editor/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BertrandBev/dlox/HEAD/editor/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /editor/assets/fonts/sourceCode/SourceCodePro-BlackItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BertrandBev/dlox/HEAD/editor/assets/fonts/sourceCode/SourceCodePro-BlackItalic.ttf -------------------------------------------------------------------------------- /editor/assets/fonts/sourceCode/SourceCodePro-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BertrandBev/dlox/HEAD/editor/assets/fonts/sourceCode/SourceCodePro-BoldItalic.ttf -------------------------------------------------------------------------------- /editor/assets/fonts/sourceCode/SourceCodePro-ExtraLight.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BertrandBev/dlox/HEAD/editor/assets/fonts/sourceCode/SourceCodePro-ExtraLight.ttf -------------------------------------------------------------------------------- /editor/assets/fonts/sourceCode/SourceCodePro-LightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BertrandBev/dlox/HEAD/editor/assets/fonts/sourceCode/SourceCodePro-LightItalic.ttf -------------------------------------------------------------------------------- /lib/test/assignment/syntax.lox: -------------------------------------------------------------------------------- 1 | // Assignment on RHS of variable. 2 | var a = "before"; 3 | var c = a = "var"; 4 | print a; // expect: var 5 | print c; // expect: var 6 | -------------------------------------------------------------------------------- /lib/test/class/local_inherit_self.lox: -------------------------------------------------------------------------------- 1 | { 2 | class Foo < Foo {} // Error at 'Foo': A class can't inherit from itself. 3 | } 4 | 5 | // Error at 'end': Unterminated block. -------------------------------------------------------------------------------- /lib/test/constructor/return_value.lox: -------------------------------------------------------------------------------- 1 | class Foo { 2 | init() { 3 | return "result"; // Error at 'return': Can't return a value from an initializer. 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /lib/test/string/literals.lox: -------------------------------------------------------------------------------- 1 | print "(" + "" + ")"; // expect: () 2 | print "a string"; // expect: a string 3 | 4 | // Non-ASCII. 5 | print "A~¶Þॐஃ"; // expect: A~¶Þॐஃ 6 | -------------------------------------------------------------------------------- /lib/test/super/super_without_name.lox: -------------------------------------------------------------------------------- 1 | class A {} 2 | 3 | class B < A { 4 | method() { 5 | super.; // Error at ';': Expect superclass method name. 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /editor/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BertrandBev/dlox/HEAD/editor/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /editor/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BertrandBev/dlox/HEAD/editor/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /editor/assets/fonts/sourceCode/SourceCodePro-MediumItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BertrandBev/dlox/HEAD/editor/assets/fonts/sourceCode/SourceCodePro-MediumItalic.ttf -------------------------------------------------------------------------------- /editor/assets/fonts/sourceCode/SourceCodePro-SemiBoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BertrandBev/dlox/HEAD/editor/assets/fonts/sourceCode/SourceCodePro-SemiBoldItalic.ttf -------------------------------------------------------------------------------- /lib/test/method/refer_to_name.lox: -------------------------------------------------------------------------------- 1 | class Foo { 2 | method() { 3 | print method; // Runtime error: Undefined variable 'method'. 4 | } 5 | } 6 | 7 | Foo().method(); 8 | -------------------------------------------------------------------------------- /lib/test/variable/shadow_and_local.lox: -------------------------------------------------------------------------------- 1 | { 2 | var a = "outer"; 3 | { 4 | print a; // expect: outer 5 | var a = "inner"; 6 | print a; // expect: inner 7 | } 8 | } -------------------------------------------------------------------------------- /lib/test/variable/shadow_local.lox: -------------------------------------------------------------------------------- 1 | { 2 | var a = "local"; 3 | { 4 | var a = "shadow"; 5 | print a; // expect: shadow 6 | } 7 | print a; // expect: local 8 | } 9 | -------------------------------------------------------------------------------- /editor/assets/fonts/sourceCode/SourceCodePro-ExtraLightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BertrandBev/dlox/HEAD/editor/assets/fonts/sourceCode/SourceCodePro-ExtraLightItalic.ttf -------------------------------------------------------------------------------- /lib/test/field/call_nonfunction_field.lox: -------------------------------------------------------------------------------- 1 | class Foo {} 2 | 3 | var foo = Foo(); 4 | foo.bar = "not fn"; 5 | 6 | foo.bar(); // Runtime error: Can only call functions and classes. 7 | -------------------------------------------------------------------------------- /lib/test/for/statement_initializer.lox: -------------------------------------------------------------------------------- 1 | // [disabled] Error at '{': Expect expression. 2 | // [disabled] Error at ')': Expect ';' after expression. 3 | // for ({}; a < 2; a = a + 1) {} 4 | -------------------------------------------------------------------------------- /lib/test/function/local_recursion.lox: -------------------------------------------------------------------------------- 1 | { 2 | fun fib(n) { 3 | if (n < 2) return n; 4 | return fib(n - 1) + fib(n - 2); 5 | } 6 | 7 | print fib(8); // expect: 21 8 | } 9 | -------------------------------------------------------------------------------- /lib/test/super/super_at_top_level.lox: -------------------------------------------------------------------------------- 1 | super.foo("bar"); // Error at 'super': Can't use 'super' outside of a class. 2 | super.foo; // Error at 'super': Can't use 'super' outside of a class. -------------------------------------------------------------------------------- /editor/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BertrandBev/dlox/HEAD/editor/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /lib/test/for/statement_condition.lox: -------------------------------------------------------------------------------- 1 | // [disabled] Error at '{': Expect expression. 2 | // [disabled] Error at ')': Expect ';' after expression. 3 | // for (var a = 1; {}; a = a + 1) {} 4 | -------------------------------------------------------------------------------- /lib/test/variable/local_from_method.lox: -------------------------------------------------------------------------------- 1 | var foo = "variable"; 2 | 3 | class Foo { 4 | method() { 5 | print foo; 6 | } 7 | } 8 | 9 | Foo().method(); // expect: variable 10 | -------------------------------------------------------------------------------- /editor/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BertrandBev/dlox/HEAD/editor/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /editor/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BertrandBev/dlox/HEAD/editor/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /lib/test/class/local_reference_self.lox: -------------------------------------------------------------------------------- 1 | { 2 | class Foo { 3 | returnSelf() { 4 | return Foo; 5 | } 6 | } 7 | 8 | print Foo().returnSelf(); // expect: Foo 9 | } 10 | -------------------------------------------------------------------------------- /editor/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BertrandBev/dlox/HEAD/editor/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /editor/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BertrandBev/dlox/HEAD/editor/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /editor/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BertrandBev/dlox/HEAD/editor/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /editor/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BertrandBev/dlox/HEAD/editor/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /editor/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BertrandBev/dlox/HEAD/editor/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /editor/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BertrandBev/dlox/HEAD/editor/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /editor/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BertrandBev/dlox/HEAD/editor/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /editor/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BertrandBev/dlox/HEAD/editor/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /editor/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BertrandBev/dlox/HEAD/editor/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /editor/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BertrandBev/dlox/HEAD/editor/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /editor/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BertrandBev/dlox/HEAD/editor/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /editor/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BertrandBev/dlox/HEAD/editor/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /editor/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BertrandBev/dlox/HEAD/editor/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /lib/test/for/return_closure.lox: -------------------------------------------------------------------------------- 1 | fun f() { 2 | for (;;) { 3 | var i = "i"; 4 | fun g() { print i; } 5 | return g; 6 | } 7 | } 8 | 9 | var h = f(); 10 | h(); // expect: i 11 | -------------------------------------------------------------------------------- /lib/test/super/no_superclass_bind.lox: -------------------------------------------------------------------------------- 1 | class Base { 2 | foo() { 3 | super.doesNotExist; // Error at 'super': Can't use 'super' in a class with no superclass. 4 | } 5 | } 6 | 7 | Base().foo(); 8 | -------------------------------------------------------------------------------- /editor/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BertrandBev/dlox/HEAD/editor/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /editor/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BertrandBev/dlox/HEAD/editor/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /lib/test/assignment/global.lox: -------------------------------------------------------------------------------- 1 | var a = "before"; 2 | print a; // expect: before 3 | 4 | a = "after"; 5 | print a; // expect: after 6 | 7 | print a = "arg"; // expect: arg 8 | print a; // expect: arg 9 | -------------------------------------------------------------------------------- /lib/test/closure/closed_closure_in_function.lox: -------------------------------------------------------------------------------- 1 | var f; 2 | 3 | { 4 | var local = "local"; 5 | fun f_() { 6 | print local; 7 | } 8 | f = f_; 9 | } 10 | 11 | f(); // expect: local 12 | -------------------------------------------------------------------------------- /lib/test/method/extra_arguments.lox: -------------------------------------------------------------------------------- 1 | class Foo { 2 | method(a, b) { 3 | print a; 4 | print b; 5 | } 6 | } 7 | 8 | Foo().method(1, 2, 3, 4); // Runtime error: Expected 2 arguments but got 4. 9 | -------------------------------------------------------------------------------- /lib/test/string/error_after_multiline.lox: -------------------------------------------------------------------------------- 1 | // Tests that we correctly track the line info across multiline strings. 2 | var a = "1 3 | 2 4 | 3 5 | "; 6 | 7 | err; // // Runtime error: Undefined variable 'err'. -------------------------------------------------------------------------------- /lib/test/super/no_superclass_call.lox: -------------------------------------------------------------------------------- 1 | class Base { 2 | foo() { 3 | super.doesNotExist(1); // Error at 'super': Can't use 'super' in a class with no superclass. 4 | } 5 | } 6 | 7 | Base().foo(); 8 | -------------------------------------------------------------------------------- /lib/test/super/parenthesized.lox: -------------------------------------------------------------------------------- 1 | class A { 2 | method() {} 3 | } 4 | 5 | class B < A { 6 | method() { 7 | (super).method(); // Error at ')': Expect '.' after 'super'. 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /lib/test/variable/early_bound.lox: -------------------------------------------------------------------------------- 1 | var a = "outer"; 2 | { 3 | fun foo() { 4 | print a; 5 | } 6 | 7 | foo(); // expect: outer 8 | var a = "inner"; 9 | foo(); // expect: outer 10 | } 11 | -------------------------------------------------------------------------------- /lib/test/variable/scope_reuse_in_different_blocks.lox: -------------------------------------------------------------------------------- 1 | { 2 | var a = "first"; 3 | print a; // expect: first 4 | } 5 | 6 | { 7 | var a = "second"; 8 | print a; // expect: second 9 | } 10 | -------------------------------------------------------------------------------- /lib/test/while/return_closure.lox: -------------------------------------------------------------------------------- 1 | fun f() { 2 | while (true) { 3 | var i = "i"; 4 | fun g() { print i; } 5 | return g; 6 | } 7 | } 8 | 9 | var h = f(); 10 | h(); // expect: i 11 | -------------------------------------------------------------------------------- /lib/test/constructor/extra_arguments.lox: -------------------------------------------------------------------------------- 1 | class Foo { 2 | init(a, b) { 3 | this.a = a; 4 | this.b = b; 5 | } 6 | } 7 | 8 | var foo = Foo(1, 2, 3, 4); // Runtime error: Expected 2 arguments but got 4. -------------------------------------------------------------------------------- /lib/test/if/dangling_else.lox: -------------------------------------------------------------------------------- 1 | // A dangling else binds to the right-most if. 2 | if (true) if (false) print "bad"; else print "good"; // expect: good 3 | if (false) if (true) print "bad"; else print "bad"; 4 | -------------------------------------------------------------------------------- /editor/android/app/src/main/kotlin/com/example/demo/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.editor 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /lib/test/closure/close_over_function_parameter.lox: -------------------------------------------------------------------------------- 1 | var f; 2 | 3 | fun foo(param) { 4 | fun f_() { 5 | print param; 6 | } 7 | f = f_; 8 | } 9 | foo("param"); 10 | 11 | f(); // expect: param 12 | -------------------------------------------------------------------------------- /lib/test/field/method.lox: -------------------------------------------------------------------------------- 1 | class Foo { 2 | bar(arg) { 3 | print arg; 4 | } 5 | } 6 | 7 | var bar = Foo().bar; 8 | print "got method"; // expect: got method 9 | bar("arg"); // expect: arg 10 | -------------------------------------------------------------------------------- /editor/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /lib/test/assignment/associativity.lox: -------------------------------------------------------------------------------- 1 | var a = "a"; 2 | var b = "b"; 3 | var c = "c"; 4 | 5 | // Assignment is right-associative. 6 | a = b = c; 7 | print a; // expect: c 8 | print b; // expect: c 9 | print c; // expect: c 10 | -------------------------------------------------------------------------------- /lib/test/assignment/local.lox: -------------------------------------------------------------------------------- 1 | { 2 | var a = "before"; 3 | print a; // expect: before 4 | 5 | a = "after"; 6 | print a; // expect: after 7 | 8 | print a = "arg"; // expect: arg 9 | print a; // expect: arg 10 | } 11 | -------------------------------------------------------------------------------- /lib/test/closure/reference_closure_multiple_times.lox: -------------------------------------------------------------------------------- 1 | var f; 2 | 3 | { 4 | var a = "a"; 5 | fun f_() { 6 | print a; 7 | print a; 8 | } 9 | f = f_; 10 | } 11 | 12 | f(); 13 | // expect: a 14 | // expect: a 15 | -------------------------------------------------------------------------------- /lib/test/constructor/early_return.lox: -------------------------------------------------------------------------------- 1 | class Foo { 2 | init() { 3 | print "init"; 4 | return; 5 | print "nope"; 6 | } 7 | } 8 | 9 | var foo = Foo(); // expect: init 10 | print foo; // expect: Foo instance 11 | -------------------------------------------------------------------------------- /lib/test/super/no_superclass_method.lox: -------------------------------------------------------------------------------- 1 | class Base {} 2 | 3 | class Derived < Base { 4 | foo() { 5 | super.doesNotExist(1); // Runtime error: Undefined property 'doesNotExist'. 6 | } 7 | } 8 | 9 | Derived().foo(); 10 | -------------------------------------------------------------------------------- /lib/test/number/literals.lox: -------------------------------------------------------------------------------- 1 | print 123; // expect: 123 2 | print 987654; // expect: 987654 3 | print 0; // expect: 0 4 | print -0; // expect: 0 5 | 6 | print 123.456; // expect: 123.456 7 | print -0.001; // expect: -0.001 8 | -------------------------------------------------------------------------------- /lib/test/constructor/return_in_nested_function.lox: -------------------------------------------------------------------------------- 1 | class Foo { 2 | init() { 3 | fun init() { 4 | return "bar"; 5 | } 6 | print init(); // expect: bar 7 | } 8 | } 9 | 10 | print Foo(); // expect: Foo instance 11 | -------------------------------------------------------------------------------- /lib/test/number/nan_equality.lox: -------------------------------------------------------------------------------- 1 | var nan = 0/0; 2 | 3 | print nan == 0; // expect: false 4 | print nan != 1; // expect: true 5 | 6 | // NaN is not equal to self. 7 | print nan == nan; // expect: false 8 | print nan != nan; // expect: true 9 | -------------------------------------------------------------------------------- /editor/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /lib/test/closure/close_over_method_parameter.lox: -------------------------------------------------------------------------------- 1 | var f; 2 | 3 | class Foo { 4 | method(param) { 5 | fun f_() { 6 | print param; 7 | } 8 | f = f_; 9 | } 10 | } 11 | 12 | Foo().method("param"); 13 | f(); // expect: param 14 | -------------------------------------------------------------------------------- /lib/test/constructor/arguments.lox: -------------------------------------------------------------------------------- 1 | class Foo { 2 | init(a, b) { 3 | print "init"; // expect: init 4 | this.a = a; 5 | this.b = b; 6 | } 7 | } 8 | 9 | var foo = Foo(1, 2); 10 | print foo.a; // expect: 1 11 | print foo.b; // expect: 2 12 | -------------------------------------------------------------------------------- /lib/test/closure/assign_to_shadowed_later.lox: -------------------------------------------------------------------------------- 1 | var a = "global"; 2 | 3 | { 4 | fun assign() { 5 | a = "assigned"; 6 | } 7 | 8 | var a = "inner"; 9 | assign(); 10 | print a; // expect: inner 11 | } 12 | 13 | print a; // expect: assigned 14 | -------------------------------------------------------------------------------- /lib/test/inheritance/constructor.lox: -------------------------------------------------------------------------------- 1 | class A { 2 | init(param) { 3 | this.field = param; 4 | } 5 | 6 | test() { 7 | print this.field; 8 | } 9 | } 10 | 11 | class B < A {} 12 | 13 | var b = B("value"); 14 | b.test(); // expect: value 15 | -------------------------------------------------------------------------------- /lib/test/comments/unicode.lox: -------------------------------------------------------------------------------- 1 | // Unicode characters are allowed in comments. 2 | // 3 | // Latin 1 Supplement: £§¶ÜÞ 4 | // Latin Extended-A: ĐĦŋœ 5 | // Latin Extended-B: ƂƢƩǁ 6 | // Other stuff: ឃᢆ᯽₪ℜ↩⊗┺░ 7 | // Emoji: ☃☺♣ 8 | 9 | print "ok"; // expect: ok 10 | -------------------------------------------------------------------------------- /lib/test/constructor/call_init_early_return.lox: -------------------------------------------------------------------------------- 1 | class Foo { 2 | init() { 3 | print "init"; 4 | return; 5 | print "nope"; 6 | } 7 | } 8 | 9 | var foo = Foo(); // expect: init 10 | print foo.init(); // expect: init 11 | // expect: Foo instance 12 | -------------------------------------------------------------------------------- /lib/test/constructor/init_not_method.lox: -------------------------------------------------------------------------------- 1 | class Foo { 2 | init(arg) { 3 | print "Foo.init(" + arg + ")"; 4 | this.field = "init"; 5 | } 6 | } 7 | 8 | fun init() { 9 | print "not initializer"; 10 | } 11 | 12 | init(); // expect: not initializer 13 | -------------------------------------------------------------------------------- /lib/test/field/call_function_field.lox: -------------------------------------------------------------------------------- 1 | class Foo {} 2 | 3 | fun bar(a, b) { 4 | print "bar"; 5 | print a; 6 | print b; 7 | } 8 | 9 | var foo = Foo(); 10 | foo.bar = bar; 11 | 12 | foo.bar(1, 2); 13 | // expect: bar 14 | // expect: 1 15 | // expect: 2 16 | -------------------------------------------------------------------------------- /lib/test/variable/in_middle_of_block.lox: -------------------------------------------------------------------------------- 1 | { 2 | var a = "a"; 3 | print a; // expect: a 4 | var b = a + " b"; 5 | print b; // expect: a b 6 | var c = a + " c"; 7 | print c; // expect: a c 8 | var d = b + " d"; 9 | print d; // expect: a b d 10 | } 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Files and directories created by pub 2 | .dart_tool/ 3 | .packages 4 | 5 | # Conventional directory for build outputs 6 | build/ 7 | 8 | # Directory created by dartdoc 9 | doc/api/ 10 | reference/ 11 | craftinginterpreters/ 12 | examples/ 13 | *.out 14 | *.exe -------------------------------------------------------------------------------- /lib/test/field/on_instance.lox: -------------------------------------------------------------------------------- 1 | class Foo {} 2 | 3 | var foo = Foo(); 4 | 5 | print foo.bar = "bar value"; // expect: bar value 6 | print foo.baz = "baz value"; // expect: baz value 7 | 8 | print foo.bar; // expect: bar value 9 | print foo.baz; // expect: baz value 10 | -------------------------------------------------------------------------------- /lib/test/logical_operator/or_truth.lox: -------------------------------------------------------------------------------- 1 | // False and nil are false. 2 | print false or "ok"; // expect: ok 3 | print nil or "ok"; // expect: ok 4 | 5 | // Everything else is true. 6 | print true or "ok"; // expect: true 7 | print 0 or "ok"; // expect: 0 8 | print "s" or "ok"; // expect: s 9 | -------------------------------------------------------------------------------- /lib/test/closure/shadow_closure_with_local.lox: -------------------------------------------------------------------------------- 1 | { 2 | var foo = "closure"; 3 | fun f() { 4 | { 5 | print foo; // expect: closure 6 | var foo = "shadow"; 7 | print foo; // expect: shadow 8 | } 9 | print foo; // expect: closure 10 | } 11 | f(); 12 | } 13 | -------------------------------------------------------------------------------- /lib/test/function/mutual_recursion.lox: -------------------------------------------------------------------------------- 1 | fun isEven(n) { 2 | if (n == 0) return true; 3 | return isOdd(n - 1); 4 | } 5 | 6 | fun isOdd(n) { 7 | if (n == 0) return false; 8 | return isEven(n - 1); 9 | } 10 | 11 | print isEven(4); // expect: true 12 | print isOdd(3); // expect: true 13 | -------------------------------------------------------------------------------- /lib/test/if/else.lox: -------------------------------------------------------------------------------- 1 | // Evaluate the 'else' expression if the condition is false. 2 | if (true) print "good"; else print "bad"; // expect: good 3 | if (false) print "bad"; else print "good"; // expect: good 4 | 5 | // Allow block body. 6 | if (false) nil; else { print "block"; } // expect: block 7 | -------------------------------------------------------------------------------- /lib/test/this/closure.lox: -------------------------------------------------------------------------------- 1 | class Foo { 2 | getClosure() { 3 | fun closure() { 4 | return this.toString(); 5 | } 6 | return closure; 7 | } 8 | 9 | toString() { return "Foo"; } 10 | } 11 | 12 | var closure = Foo().getClosure(); 13 | print closure(); // expect: Foo 14 | -------------------------------------------------------------------------------- /lib/test/logical_operator/and_truth.lox: -------------------------------------------------------------------------------- 1 | // False and nil are false. 2 | print false and "bad"; // expect: false 3 | print nil and "bad"; // expect: nil 4 | 5 | // Everything else is true. 6 | print true and "ok"; // expect: ok 7 | print 0 and "ok"; // expect: ok 8 | print "" and "ok"; // expect: ok 9 | -------------------------------------------------------------------------------- /lib/test/super/missing_arguments.lox: -------------------------------------------------------------------------------- 1 | class Base { 2 | foo(a, b) { 3 | print "Base.foo(" + a + ", " + b + ")"; 4 | } 5 | } 6 | 7 | class Derived < Base { 8 | foo() { 9 | super.foo(1); // Runtime error: Expected 2 arguments but got 1. 10 | } 11 | } 12 | 13 | Derived().foo(); 14 | -------------------------------------------------------------------------------- /editor/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip 7 | -------------------------------------------------------------------------------- /lib/test/super/indirectly_inherited.lox: -------------------------------------------------------------------------------- 1 | class A { 2 | foo() { 3 | print "A.foo()"; 4 | } 5 | } 6 | 7 | class B < A {} 8 | 9 | class C < B { 10 | foo() { 11 | print "C.foo()"; 12 | super.foo(); 13 | } 14 | } 15 | 16 | C().foo(); 17 | // expect: C.foo() 18 | // expect: A.foo() 19 | -------------------------------------------------------------------------------- /lib/test/super/call_same_method.lox: -------------------------------------------------------------------------------- 1 | class Base { 2 | foo() { 3 | print "Base.foo()"; 4 | } 5 | } 6 | 7 | class Derived < Base { 8 | foo() { 9 | print "Derived.foo()"; 10 | super.foo(); 11 | } 12 | } 13 | 14 | Derived().foo(); 15 | // expect: Derived.foo() 16 | // expect: Base.foo() 17 | -------------------------------------------------------------------------------- /lib/test/function/local_mutual_recursion.lox: -------------------------------------------------------------------------------- 1 | { 2 | fun isEven(n) { 3 | if (n == 0) return true; 4 | return isOdd(n - 1); // Runtime error: Undefined variable 'isOdd'. 5 | } 6 | 7 | fun isOdd(n) { 8 | if (n == 0) return false; 9 | return isEven(n - 1); 10 | } 11 | 12 | isEven(4); 13 | } -------------------------------------------------------------------------------- /lib/test/super/call_other_method.lox: -------------------------------------------------------------------------------- 1 | class Base { 2 | foo() { 3 | print "Base.foo()"; 4 | } 5 | } 6 | 7 | class Derived < Base { 8 | bar() { 9 | print "Derived.bar()"; 10 | super.foo(); 11 | } 12 | } 13 | 14 | Derived().bar(); 15 | // expect: Derived.bar() 16 | // expect: Base.foo() 17 | -------------------------------------------------------------------------------- /editor/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /lib/test/if/truth.lox: -------------------------------------------------------------------------------- 1 | // False and nil are false. 2 | if (false) print "bad"; else print "false"; // expect: false 3 | if (nil) print "bad"; else print "nil"; // expect: nil 4 | 5 | // Everything else is true. 6 | if (true) print true; // expect: true 7 | if (0) print 0; // expect: 0 8 | if ("") print "empty"; // expect: empty 9 | -------------------------------------------------------------------------------- /editor/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /editor/android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 11 | key.properties 12 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: dlox 2 | description: A sample command-line application. 3 | # version: 1.0.0 4 | # homepage: https://www.example.com 5 | 6 | environment: 7 | sdk: '>=2.9.3 <3.0.0' 8 | 9 | #dependencies: 10 | # path: ^1.7.0 11 | 12 | dev_dependencies: 13 | pedantic: ^1.9.0 14 | test: ^1.14.4 15 | sprintf: ^6.0.0 16 | -------------------------------------------------------------------------------- /editor/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /lib/test/if/if.lox: -------------------------------------------------------------------------------- 1 | // Evaluate the 'then' expression if the condition is true. 2 | if (true) print "good"; // expect: good 3 | if (false) print "bad"; 4 | 5 | // Allow block body. 6 | if (true) { print "block"; } // expect: block 7 | 8 | // Assignment in if condition. 9 | var a = false; 10 | if (a = true) print a; // expect: true 11 | -------------------------------------------------------------------------------- /lib/test/super/this_in_superclass_method.lox: -------------------------------------------------------------------------------- 1 | class Base { 2 | init(a) { 3 | this.a = a; 4 | } 5 | } 6 | 7 | class Derived < Base { 8 | init(a, b) { 9 | super.init(a); 10 | this.b = b; 11 | } 12 | } 13 | 14 | var derived = Derived("a", "b"); 15 | print derived.a; // expect: a 16 | print derived.b; // expect: b 17 | -------------------------------------------------------------------------------- /lib/test/super/constructor.lox: -------------------------------------------------------------------------------- 1 | class Base { 2 | init(a, b) { 3 | print "Base.init(" + a + ", " + b + ")"; 4 | } 5 | } 6 | 7 | class Derived < Base { 8 | init() { 9 | print "Derived.init()"; 10 | super.init("a", "b"); 11 | } 12 | } 13 | 14 | Derived(); 15 | // expect: Derived.init() 16 | // expect: Base.init(a, b) 17 | -------------------------------------------------------------------------------- /lib/test/super/super_in_inherited_method.lox: -------------------------------------------------------------------------------- 1 | class A { 2 | say() { 3 | print "A"; 4 | } 5 | } 6 | 7 | class B < A { 8 | test() { 9 | super.say(); 10 | } 11 | 12 | say() { 13 | print "B"; 14 | } 15 | } 16 | 17 | class C < B { 18 | say() { 19 | print "C"; 20 | } 21 | } 22 | 23 | C().test(); // expect: A 24 | -------------------------------------------------------------------------------- /editor/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /lib/test/closure/reuse_closure_slot.lox: -------------------------------------------------------------------------------- 1 | { 2 | var f; 3 | 4 | { 5 | var a = "a"; 6 | fun f_() { print a; } 7 | f = f_; 8 | } 9 | 10 | { 11 | // Since a is out of scope, the local slot will be reused by b. Make sure 12 | // that f still closes over a. 13 | var b = "b"; 14 | f(); // expect: a 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /lib/test/while/closure_in_body.lox: -------------------------------------------------------------------------------- 1 | var f1; 2 | var f2; 3 | var f3; 4 | 5 | var i = 1; 6 | while (i < 4) { 7 | var j = i; 8 | fun f() { print j; } 9 | 10 | if (j == 1) f1 = f; 11 | else if (j == 2) f2 = f; 12 | else f3 = f; 13 | 14 | i = i + 1; 15 | } 16 | 17 | f1(); // expect: 1 18 | f2(); // expect: 2 19 | f3(); // expect: 3 20 | -------------------------------------------------------------------------------- /lib/test/operator/equals_method.lox: -------------------------------------------------------------------------------- 1 | // Bound methods have identity equality. 2 | class Foo { 3 | method() {} 4 | } 5 | 6 | var foo = Foo(); 7 | var fooMethod = foo.method; 8 | 9 | // Same bound method. 10 | print fooMethod == fooMethod; // expect: true 11 | 12 | // Different closurizations. 13 | print foo.method == foo.method; // expect: false 14 | -------------------------------------------------------------------------------- /editor/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: 198df796aa80073ef22bdf249e614e2ff33c6895 8 | channel: beta 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /editor/assets/snippets/closure.lox: -------------------------------------------------------------------------------- 1 | fun buildCounter() { 2 | var count = 0; 3 | 4 | fun increment() { 5 | // Captures the enclosing scope's local variable 6 | count += 1; 7 | print count; 8 | } 9 | 10 | return increment; 11 | } 12 | 13 | var increment = buildCounter(); 14 | // Local variable count has been closed on 15 | increment(); 16 | -------------------------------------------------------------------------------- /editor/assets/snippets/fibonacci.lox: -------------------------------------------------------------------------------- 1 | // A slow but pretty recursive implementation 2 | fun fib(n) { 3 | if (n <= 1) return n; 4 | return fib(n - 2) + fib(n - 1); 5 | } 6 | 7 | // Print N first numbers 8 | var N = 6; 9 | var buf = "["; 10 | for (var k = 0; k < N; k += 1) { 11 | buf += fib(k); 12 | if (k < N - 1) buf += ", "; 13 | } 14 | print buf + "]"; -------------------------------------------------------------------------------- /lib/test/operator/not.lox: -------------------------------------------------------------------------------- 1 | print !true; // expect: false 2 | print !false; // expect: true 3 | print !!true; // expect: true 4 | 5 | print !123; // expect: false 6 | print !0; // expect: false 7 | 8 | print !nil; // expect: true 9 | 10 | print !""; // expect: false 11 | 12 | fun foo() {} 13 | print !foo; // expect: false 14 | -------------------------------------------------------------------------------- /lib/test/super/extra_arguments.lox: -------------------------------------------------------------------------------- 1 | class Base { 2 | foo(a, b) { 3 | print "Base.foo(" + a + ", " + b + ")"; 4 | } 5 | } 6 | 7 | class Derived < Base { 8 | foo() { 9 | print "Derived.foo()"; // expect: Derived.foo() 10 | super.foo("a", "b", "c", "d"); // Runtime error: Expected 2 arguments but got 4. 11 | } 12 | } 13 | 14 | Derived().foo(); 15 | -------------------------------------------------------------------------------- /lib/test/super/bound_method.lox: -------------------------------------------------------------------------------- 1 | class A { 2 | method(arg) { 3 | print "A.method(" + arg + ")"; 4 | } 5 | } 6 | 7 | class B < A { 8 | getClosure() { 9 | return super.method; 10 | } 11 | 12 | method(arg) { 13 | print "B.method(" + arg + ")"; 14 | } 15 | } 16 | 17 | 18 | var closure = B().getClosure(); 19 | closure("arg"); // expect: A.method(arg) 20 | -------------------------------------------------------------------------------- /lib/test/inheritance/inherit_methods.lox: -------------------------------------------------------------------------------- 1 | class Foo { 2 | methodOnFoo() { print "foo"; } 3 | override() { print "foo"; } 4 | } 5 | 6 | class Bar < Foo { 7 | methodOnBar() { print "bar"; } 8 | override() { print "bar"; } 9 | } 10 | 11 | var bar = Bar(); 12 | bar.methodOnFoo(); // expect: foo 13 | bar.methodOnBar(); // expect: bar 14 | bar.override(); // expect: bar 15 | -------------------------------------------------------------------------------- /lib/test/super/closure.lox: -------------------------------------------------------------------------------- 1 | class Base { 2 | toString() { return "Base"; } 3 | } 4 | 5 | class Derived < Base { 6 | getClosure() { 7 | fun closure() { 8 | return super.toString(); 9 | } 10 | return closure; 11 | } 12 | 13 | toString() { return "Derived"; } 14 | } 15 | 16 | var closure = Derived().getClosure(); 17 | print closure(); // expect: Base 18 | -------------------------------------------------------------------------------- /editor/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /editor/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /editor/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /lib/test/class/inherited_method.lox: -------------------------------------------------------------------------------- 1 | class Foo { 2 | inFoo() { 3 | print "in foo"; 4 | } 5 | } 6 | 7 | class Bar < Foo { 8 | inBar() { 9 | print "in bar"; 10 | } 11 | } 12 | 13 | class Baz < Bar { 14 | inBaz() { 15 | print "in baz"; 16 | } 17 | } 18 | 19 | var baz = Baz(); 20 | baz.inFoo(); // expect: in foo 21 | baz.inBar(); // expect: in bar 22 | baz.inBaz(); // expect: in baz 23 | -------------------------------------------------------------------------------- /lib/test/this/nested_closure.lox: -------------------------------------------------------------------------------- 1 | class Foo { 2 | getClosure() { 3 | fun f() { 4 | fun g() { 5 | fun h() { 6 | return this.toString(); 7 | } 8 | return h; 9 | } 10 | return g; 11 | } 12 | return f; 13 | } 14 | 15 | toString() { return "Foo"; } 16 | } 17 | 18 | var closure = Foo().getClosure(); 19 | print closure()()(); // expect: Foo 20 | -------------------------------------------------------------------------------- /lib/test/field/method_binds_this.lox: -------------------------------------------------------------------------------- 1 | class Foo { 2 | sayName(a) { 3 | print this.name; 4 | print a; 5 | } 6 | } 7 | 8 | var foo1 = Foo(); 9 | foo1.name = "foo1"; 10 | 11 | var foo2 = Foo(); 12 | foo2.name = "foo2"; 13 | 14 | // Store the method reference on another object. 15 | foo2.fn = foo1.sayName; 16 | // Still retains original receiver. 17 | foo2.fn(1); 18 | // expect: foo1 19 | // expect: 1 20 | -------------------------------------------------------------------------------- /lib/test/closure/nested_closure.lox: -------------------------------------------------------------------------------- 1 | var f; 2 | 3 | fun f1() { 4 | var a = "a"; 5 | fun f2() { 6 | var b = "b"; 7 | fun f3() { 8 | var c = "c"; 9 | fun f4() { 10 | print a; 11 | print b; 12 | print c; 13 | } 14 | f = f4; 15 | } 16 | f3(); 17 | } 18 | f2(); 19 | } 20 | f1(); 21 | 22 | f(); 23 | // expect: a 24 | // expect: b 25 | // expect: c 26 | -------------------------------------------------------------------------------- /lib/test/this/nested_class.lox: -------------------------------------------------------------------------------- 1 | class Outer { 2 | method() { 3 | print this; // expect: Outer instance 4 | 5 | fun f() { 6 | print this; // expect: Outer instance 7 | 8 | class Inner { 9 | method() { 10 | print this; // expect: Inner instance 11 | } 12 | } 13 | 14 | Inner().method(); 15 | } 16 | f(); 17 | } 18 | } 19 | 20 | Outer().method(); 21 | -------------------------------------------------------------------------------- /lib/test/closure/unused_closure.lox: -------------------------------------------------------------------------------- 1 | // This is a regression test. There was a bug where the VM would try to close 2 | // an upvalue even if the upvalue was never created because the codepath for 3 | // the closure was not executed. 4 | 5 | { 6 | var a = "a"; 7 | if (false) { 8 | fun foo() { a; } 9 | } 10 | } 11 | 12 | // If we get here, we didn't segfault when a went out of scope. 13 | print "ok"; // expect: ok 14 | -------------------------------------------------------------------------------- /lib/test/for/closure_in_body.lox: -------------------------------------------------------------------------------- 1 | var f1; 2 | var f2; 3 | var f3; 4 | 5 | for (var i = 1; i < 4; i = i + 1) { 6 | var j = i; 7 | fun f() { 8 | print i; 9 | print j; 10 | } 11 | 12 | if (j == 1) f1 = f; 13 | else if (j == 2) f2 = f; 14 | else f3 = f; 15 | } 16 | 17 | f1(); // expect: 4 18 | // expect: 1 19 | f2(); // expect: 4 20 | // expect: 2 21 | f3(); // expect: 4 22 | // expect: 3 23 | -------------------------------------------------------------------------------- /lib/test/super/super_in_closure_in_inherited_method.lox: -------------------------------------------------------------------------------- 1 | class A { 2 | say() { 3 | print "A"; 4 | } 5 | } 6 | 7 | class B < A { 8 | getClosure() { 9 | fun closure() { 10 | super.say(); 11 | } 12 | return closure; 13 | } 14 | 15 | say() { 16 | print "B"; 17 | } 18 | } 19 | 20 | class C < B { 21 | say() { 22 | print "C"; 23 | } 24 | } 25 | 26 | C().getClosure()(); // expect: A 27 | -------------------------------------------------------------------------------- /lib/test/operator/equals.lox: -------------------------------------------------------------------------------- 1 | print nil == nil; // expect: true 2 | 3 | print true == true; // expect: true 4 | print true == false; // expect: false 5 | 6 | print 1 == 1; // expect: true 7 | print 1 == 2; // expect: false 8 | 9 | print "str" == "str"; // expect: true 10 | print "str" == "ing"; // expect: false 11 | 12 | print nil == false; // expect: false 13 | print false == 0; // expect: false 14 | print 0 == "0"; // expect: false 15 | -------------------------------------------------------------------------------- /lib/test/operator/equals_class.lox: -------------------------------------------------------------------------------- 1 | // Bound methods have identity equality. 2 | class Foo {} 3 | class Bar {} 4 | 5 | print Foo == Foo; // expect: true 6 | print Foo == Bar; // expect: false 7 | print Bar == Foo; // expect: false 8 | print Bar == Bar; // expect: true 9 | 10 | print Foo == "Foo"; // expect: false 11 | print Foo == nil; // expect: false 12 | print Foo == 123; // expect: false 13 | print Foo == true; // expect: false 14 | -------------------------------------------------------------------------------- /lib/test/operator/not_equals.lox: -------------------------------------------------------------------------------- 1 | print nil != nil; // expect: false 2 | 3 | print true != true; // expect: false 4 | print true != false; // expect: true 5 | 6 | print 1 != 1; // expect: false 7 | print 1 != 2; // expect: true 8 | 9 | print "str" != "str"; // expect: false 10 | print "str" != "ing"; // expect: true 11 | 12 | print nil != false; // expect: true 13 | print false != 0; // expect: true 14 | print 0 != "0"; // expect: true 15 | -------------------------------------------------------------------------------- /lib/test/constructor/call_init_explicitly.lox: -------------------------------------------------------------------------------- 1 | class Foo { 2 | init(arg) { 3 | print "Foo.init(" + arg + ")"; 4 | this.field = "init"; 5 | } 6 | } 7 | 8 | var foo = Foo("one"); // expect: Foo.init(one) 9 | foo.field = "field"; 10 | 11 | var foo2 = foo.init("two"); // expect: Foo.init(two) 12 | print foo2; // expect: Foo instance 13 | 14 | // Make sure init() doesn't create a fresh instance. 15 | print foo.field; // expect: init 16 | -------------------------------------------------------------------------------- /lib/test/while/syntax.lox: -------------------------------------------------------------------------------- 1 | // Single-expression body. 2 | var c = 0; 3 | while (c < 3) print c = c + 1; 4 | // expect: 1 5 | // expect: 2 6 | // expect: 3 7 | 8 | // Block body. 9 | var a = 0; 10 | while (a < 3) { 11 | print a; 12 | a = a + 1; 13 | } 14 | // expect: 0 15 | // expect: 1 16 | // expect: 2 17 | 18 | // Statement bodies. 19 | while (false) if (true) 1; else 2; 20 | while (false) while (true) 1; 21 | while (false) for (;;) 1; 22 | -------------------------------------------------------------------------------- /lib/test/closure/assign_to_closure.lox: -------------------------------------------------------------------------------- 1 | var f; 2 | var g; 3 | 4 | { 5 | var local = "local"; 6 | fun f_() { 7 | print local; 8 | local = "after f"; 9 | print local; 10 | } 11 | f = f_; 12 | 13 | fun g_() { 14 | print local; 15 | local = "after g"; 16 | print local; 17 | } 18 | g = g_; 19 | } 20 | 21 | f(); 22 | // expect: local 23 | // expect: after f 24 | 25 | g(); 26 | // expect: after f 27 | // expect: after g 28 | -------------------------------------------------------------------------------- /lib/test/super/reassign_superclass.lox: -------------------------------------------------------------------------------- 1 | class Base { 2 | method() { 3 | print "Base.method()"; 4 | } 5 | } 6 | 7 | class Derived < Base { 8 | method() { 9 | super.method(); 10 | } 11 | } 12 | 13 | class OtherBase { 14 | method() { 15 | print "OtherBase.method()"; 16 | } 17 | } 18 | 19 | var derived = Derived(); 20 | derived.method(); // expect: Base.method() 21 | Base = OtherBase; 22 | derived.method(); // expect: Base.method() 23 | -------------------------------------------------------------------------------- /editor/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | # package.json "deploy": "yarn build; push-dir --dir=dist --branch=gh-pages --cleanup" 3 | 4 | # abort on errors 5 | set -e 6 | 7 | # build 8 | flutter build web --release --no-sound-null-safety 9 | 10 | # navigate into the build output directory 11 | cd build/web 12 | 13 | # Commit repo 14 | git init 15 | git add -A 16 | git commit -m 'deploy' 17 | git push -f git@github.com:BertrandBev/dlox.git master:gh-pages 18 | 19 | # Nav back 20 | cd - -------------------------------------------------------------------------------- /lib/test/regression/40.lox: -------------------------------------------------------------------------------- 1 | fun caller(g) { 2 | g(); 3 | // g should be a function, not nil. 4 | print g == nil; // expect: false 5 | } 6 | 7 | fun callCaller() { 8 | var capturedVar = "before"; 9 | var a = "a"; 10 | 11 | fun f() { 12 | // Commenting the next line out prevents the bug! 13 | capturedVar = "after"; 14 | 15 | // Returning anything also fixes it, even nil: 16 | //return nil; 17 | } 18 | 19 | caller(f); 20 | } 21 | 22 | callCaller(); 23 | -------------------------------------------------------------------------------- /editor/ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /lib/test/closure/close_over_later_variable.lox: -------------------------------------------------------------------------------- 1 | // This is a regression test. There was a bug where if an upvalue for an 2 | // earlier local (here "a") was captured *after* a later one ("b"), then it 3 | // would crash because it walked to the end of the upvalue list (correct), but 4 | // then didn't handle not finding the variable. 5 | 6 | fun f() { 7 | var a = "a"; 8 | var b = "b"; 9 | fun g() { 10 | print b; // expect: b 11 | print a; // expect: a 12 | } 13 | g(); 14 | } 15 | f(); 16 | -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # Defines a default set of lint rules enforced for 2 | # projects at Google. For details and rationale, 3 | # see https://github.com/dart-lang/pedantic#enabled-lints. 4 | include: package:pedantic/analysis_options.yaml 5 | 6 | # For lint rules and documentation, see http://dart-lang.github.io/linter/lints. 7 | # Uncomment to specify additional rules. 8 | # linter: 9 | # rules: 10 | # - camel_case_types 11 | 12 | analyzer: 13 | # exclude: 14 | # - path/to/excluded/files/** 15 | -------------------------------------------------------------------------------- /editor/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 4 | def properties = new Properties() 5 | 6 | assert localPropertiesFile.exists() 7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 8 | 9 | def flutterSdkPath = properties.getProperty("flutter.sdk") 10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" 12 | -------------------------------------------------------------------------------- /editor/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /editor/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/test/field/get_and_set_method.lox: -------------------------------------------------------------------------------- 1 | // Bound methods have identity equality. 2 | class Foo { 3 | method(a) { 4 | print "method"; 5 | print a; 6 | } 7 | other(a) { 8 | print "other"; 9 | print a; 10 | } 11 | } 12 | 13 | var foo = Foo(); 14 | var method = foo.method; 15 | 16 | // Setting a property shadows the instance method. 17 | foo.method = foo.other; 18 | foo.method(1); 19 | // expect: other 20 | // expect: 1 21 | 22 | // The old method handle still points to the original method. 23 | method(2); 24 | // expect: method 25 | // expect: 2 26 | -------------------------------------------------------------------------------- /editor/assets/snippets/benchmark.lox: -------------------------------------------------------------------------------- 1 | // To get good performances, disable the VM trace 2 | fun benchmark() { 3 | var start = clock(); 4 | var list = []; 5 | for (var k = 0; k < 100000; k += 1) { 6 | list.add(k); 7 | } 8 | var elapsed = clock() - start; 9 | print "Creating list: " + elapsed + "ms"; 10 | start = clock(); 11 | var sum = 0; 12 | for (var k = 0; k < list.length(); k += 1) { 13 | sum += list[k]; 14 | } 15 | // sum /= list.length(); 16 | elapsed = clock() - start; 17 | print "Averaging: " + elapsed + "ms"; 18 | } 19 | 20 | benchmark(); -------------------------------------------------------------------------------- /editor/assets/snippets/linked_list.lox: -------------------------------------------------------------------------------- 1 | class Node { 2 | // Initialize a linkedlist node 3 | init(val, next) { 4 | this.val = val; 5 | this.next = next; 6 | } 7 | 8 | // Traverse the linked-list and print it in a string 9 | toString() { 10 | var buf = "["; 11 | var node = this; 12 | while (node != nil) { 13 | buf += node.val; 14 | node = node.next; 15 | if (node != nil) 16 | buf += ", "; 17 | } 18 | return buf + "]"; 19 | } 20 | } 21 | 22 | var c = Node("c", nil); 23 | var b = Node("b", c); 24 | var a = Node("a", b); 25 | 26 | print a.toString(); -------------------------------------------------------------------------------- /lib/table.dart: -------------------------------------------------------------------------------- 1 | class Table { 2 | // Optimisation: replace with MAP 3 | final data = {}; 4 | 5 | Object getVal(String key) { 6 | return data[key]; 7 | } 8 | 9 | bool setVal(String key, Object val) { 10 | final hadKey = data.containsKey(key); 11 | data[key] = val; 12 | return !hadKey; 13 | } 14 | 15 | void delete(String key) { 16 | data.remove(key); 17 | } 18 | 19 | void addAll(Table other) { 20 | data.addAll(other.data); 21 | } 22 | 23 | Object findString(String str) { 24 | // Optimisation: key on hashKeys 25 | return data[str]; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /lib/test/for/scope.lox: -------------------------------------------------------------------------------- 1 | { 2 | var i = "before"; 3 | 4 | // New variable is in inner scope. 5 | for (var i = 0; i < 1; i = i + 1) { 6 | print i; // expect: 0 7 | 8 | // Loop body is in second inner scope. 9 | var i = -1; 10 | print i; // expect: -1 11 | } 12 | } 13 | 14 | { 15 | // New variable shadows outer variable. 16 | for (var i = 0; i > 0; i = i + 1) {} 17 | 18 | // Goes out of scope after loop. 19 | var i = "after"; 20 | print i; // expect: after 21 | 22 | // Can reuse an existing variable. 23 | for (i = 0; i < 1; i = i + 1) { 24 | print i; // expect: 0 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /lib/test/logical_operator/and.lox: -------------------------------------------------------------------------------- 1 | // Note: These tests implicitly depend on ints being truthy. 2 | 3 | // Return the first non-true argument. 4 | print false and 1; // expect: false 5 | print true and 1; // expect: 1 6 | print 1 and 2 and false; // expect: false 7 | 8 | // Return the last argument if all are true. 9 | print 1 and true; // expect: true 10 | print 1 and 2 and 3; // expect: 3 11 | 12 | // Short-circuit at the first false argument. 13 | var a = "before"; 14 | var b = "before"; 15 | (a = true) and 16 | (b = false) and 17 | (a = "bad"); 18 | print a; // expect: true 19 | print b; // expect: false 20 | -------------------------------------------------------------------------------- /lib/test/logical_operator/or.lox: -------------------------------------------------------------------------------- 1 | // Note: These tests implicitly depend on ints being truthy. 2 | 3 | // Return the first true argument. 4 | print 1 or true; // expect: 1 5 | print false or 1; // expect: 1 6 | print false or false or true; // expect: true 7 | 8 | // Return the last argument if all are false. 9 | print false or false; // expect: false 10 | print false or false or false; // expect: false 11 | 12 | // Short-circuit at the first true argument. 13 | var a = "before"; 14 | var b = "before"; 15 | (a = false) or 16 | (b = true) or 17 | (a = "bad"); 18 | print a; // expect: false 19 | print b; // expect: true 20 | -------------------------------------------------------------------------------- /editor/web/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "editor", 3 | "short_name": "editor", 4 | "start_url": ".", 5 | "display": "standalone", 6 | "background_color": "#0175C2", 7 | "theme_color": "#0175C2", 8 | "description": "A new Flutter project.", 9 | "orientation": "portrait-primary", 10 | "prefer_related_applications": false, 11 | "icons": [ 12 | { 13 | "src": "icons/Icon-192.png", 14 | "sizes": "192x192", 15 | "type": "image/png" 16 | }, 17 | { 18 | "src": "icons/Icon-512.png", 19 | "sizes": "512x512", 20 | "type": "image/png" 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /editor/ios/.gitignore: -------------------------------------------------------------------------------- 1 | *.mode1v3 2 | *.mode2v3 3 | *.moved-aside 4 | *.pbxuser 5 | *.perspectivev3 6 | **/*sync/ 7 | .sconsign.dblite 8 | .tags* 9 | **/.vagrant/ 10 | **/DerivedData/ 11 | Icon? 12 | **/Pods/ 13 | **/.symlinks/ 14 | profile 15 | xcuserdata 16 | **/.generated/ 17 | Flutter/App.framework 18 | Flutter/Flutter.framework 19 | Flutter/Flutter.podspec 20 | Flutter/Generated.xcconfig 21 | Flutter/app.flx 22 | Flutter/app.zip 23 | Flutter/flutter_assets/ 24 | Flutter/flutter_export_environment.sh 25 | ServiceDefinitions.json 26 | Runner/GeneratedPluginRegistrant.* 27 | 28 | # Exceptions to above rules. 29 | !default.mode1v3 30 | !default.mode2v3 31 | !default.pbxuser 32 | !default.perspectivev3 33 | -------------------------------------------------------------------------------- /lib/test/closure/unused_later_closure.lox: -------------------------------------------------------------------------------- 1 | // This is a regression test. When closing upvalues for discarded locals, it 2 | // wouldn't make sure it discarded the upvalue for the correct stack slot. 3 | // 4 | // Here we create two locals that can be closed over, but only the first one 5 | // actually is. When "b" goes out of scope, we need to make sure we don't 6 | // prematurely close "a". 7 | var closure; 8 | 9 | { 10 | var a = "a"; 11 | 12 | { 13 | var b = "b"; 14 | fun returnA() { 15 | return a; 16 | } 17 | 18 | closure = returnA; 19 | 20 | if (false) { 21 | fun returnB() { 22 | return b; 23 | } 24 | } 25 | } 26 | 27 | print closure(); // expect: a 28 | } 29 | -------------------------------------------------------------------------------- /lib/test/inheritance/set_fields_from_base_class.lox: -------------------------------------------------------------------------------- 1 | class Foo { 2 | foo(a, b) { 3 | this.field1 = a; 4 | this.field2 = b; 5 | } 6 | 7 | fooPrint() { 8 | print this.field1; 9 | print this.field2; 10 | } 11 | } 12 | 13 | class Bar < Foo { 14 | bar(a, b) { 15 | this.field1 = a; 16 | this.field2 = b; 17 | } 18 | 19 | barPrint() { 20 | print this.field1; 21 | print this.field2; 22 | } 23 | } 24 | 25 | var bar = Bar(); 26 | bar.foo("foo 1", "foo 2"); 27 | bar.fooPrint(); 28 | // expect: foo 1 29 | // expect: foo 2 30 | 31 | bar.bar("bar 1", "bar 2"); 32 | bar.barPrint(); 33 | // expect: bar 1 34 | // expect: bar 2 35 | 36 | bar.fooPrint(); 37 | // expect: bar 1 38 | // expect: bar 2 39 | -------------------------------------------------------------------------------- /editor/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.3.50' 3 | repositories { 4 | google() 5 | jcenter() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:3.5.0' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | jcenter() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | } 25 | subprojects { 26 | project.evaluationDependsOn(':app') 27 | } 28 | 29 | task clean(type: Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /editor/assets/snippets/containers.lox: -------------------------------------------------------------------------------- 1 | fun exploreList() { 2 | // Mixed type list container 3 | var list = [1, "two", [3, 4]]; 4 | print list; 5 | print list[1:]; 6 | print list[:-1]; 7 | for v, k in list { 8 | print k + " " + v; 9 | } 10 | } 11 | 12 | fun exploreMap() { 13 | // Mixed type map container 14 | var map = {"a": 1, "b": "string", "c": [1, 2]}; 15 | print map; 16 | print map["a"]; 17 | for v, k in map { 18 | print k + " " + v; 19 | } 20 | } 21 | 22 | fun exploreStrings() { 23 | // String operations 24 | var str = "list: "; 25 | str += [1, 2]; 26 | str += " " + {1: 2} + "#"; 27 | print str[:-1]; 28 | for v, k in str[:4] { 29 | print k + " " + v; 30 | } 31 | 32 | } 33 | 34 | exploreList(); 35 | exploreMap(); 36 | exploreStrings(); -------------------------------------------------------------------------------- /lib/test/operator/comparison.lox: -------------------------------------------------------------------------------- 1 | print 1 < 2; // expect: true 2 | print 2 < 2; // expect: false 3 | print 2 < 1; // expect: false 4 | 5 | print 1 <= 2; // expect: true 6 | print 2 <= 2; // expect: true 7 | print 2 <= 1; // expect: false 8 | 9 | print 1 > 2; // expect: false 10 | print 2 > 2; // expect: false 11 | print 2 > 1; // expect: true 12 | 13 | print 1 >= 2; // expect: false 14 | print 2 >= 2; // expect: true 15 | print 2 >= 1; // expect: true 16 | 17 | // Zero and negative zero compare the same. 18 | print 0 < -0; // expect: false 19 | print -0 < 0; // expect: false 20 | print 0 > -0; // expect: false 21 | print -0 > 0; // expect: false 22 | print 0 <= -0; // expect: true 23 | print -0 <= 0; // expect: true 24 | print 0 >= -0; // expect: true 25 | print -0 >= 0; // expect: true 26 | -------------------------------------------------------------------------------- /editor/assets/snippets/inheritance.lox: -------------------------------------------------------------------------------- 1 | // 'Abstract' vehicle class 2 | class Vehicle { 3 | speakUp() { 4 | var prefix = "Chugging along"; 5 | if (this.speed > 30) prefix = "Speeding around"; 6 | var buf = prefix + " at " + this.speed + " mph"; 7 | print buf + " on my " + this.wheels + " wheels!"; 8 | } 9 | 10 | illegalSpeed() { 11 | return 130; 12 | } 13 | } 14 | 15 | // Inherits from superclass Vehicle 16 | class Tractor < Vehicle { 17 | init(speed) { 18 | this.speed = speed; 19 | this.wheels = 4; 20 | } 21 | } 22 | 23 | // Inherits from superclass Vehicle 24 | class Superbike < Vehicle { 25 | init() { 26 | this.speed = super.illegalSpeed(); 27 | this.wheels = 2; 28 | } 29 | } 30 | 31 | var tractor = Tractor(25); 32 | tractor.speakUp(); 33 | 34 | var superbike = Superbike(); 35 | superbike.speakUp(); 36 | -------------------------------------------------------------------------------- /lib/test/function/parameters.lox: -------------------------------------------------------------------------------- 1 | fun f0() { return 0; } 2 | print f0(); // expect: 0 3 | 4 | fun f1(a) { return a; } 5 | print f1(1); // expect: 1 6 | 7 | fun f2(a, b) { return a + b; } 8 | print f2(1, 2); // expect: 3 9 | 10 | fun f3(a, b, c) { return a + b + c; } 11 | print f3(1, 2, 3); // expect: 6 12 | 13 | fun f4(a, b, c, d) { return a + b + c + d; } 14 | print f4(1, 2, 3, 4); // expect: 10 15 | 16 | fun f5(a, b, c, d, e) { return a + b + c + d + e; } 17 | print f5(1, 2, 3, 4, 5); // expect: 15 18 | 19 | fun f6(a, b, c, d, e, f) { return a + b + c + d + e + f; } 20 | print f6(1, 2, 3, 4, 5, 6); // expect: 21 21 | 22 | fun f7(a, b, c, d, e, f, g) { return a + b + c + d + e + f + g; } 23 | print f7(1, 2, 3, 4, 5, 6, 7); // expect: 28 24 | 25 | fun f8(a, b, c, d, e, f, g, h) { return a + b + c + d + e + f + g + h; } 26 | print f8(1, 2, 3, 4, 5, 6, 7, 8); // expect: 36 27 | -------------------------------------------------------------------------------- /lib/test/bool/equality.lox: -------------------------------------------------------------------------------- 1 | print true == true; // expect: true 2 | print true == false; // expect: false 3 | print false == true; // expect: false 4 | print false == false; // expect: true 5 | 6 | // Not equal to other types. 7 | print true == 1; // expect: false 8 | print false == 0; // expect: false 9 | print true == "true"; // expect: false 10 | print false == "false"; // expect: false 11 | print false == ""; // expect: false 12 | 13 | print true != true; // expect: false 14 | print true != false; // expect: true 15 | print false != true; // expect: true 16 | print false != false; // expect: false 17 | 18 | // Not equal to other types. 19 | print true != 1; // expect: true 20 | print false != 0; // expect: true 21 | print true != "true"; // expect: true 22 | print false != "false"; // expect: true 23 | print false != ""; // expect: true 24 | -------------------------------------------------------------------------------- /editor/lib/constants.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class ColorTheme { 4 | static Color terminal = Color(0xFF131313); 5 | static Color editor = Color(0xFF282828); 6 | static Color sidebar = Color(0xFF1E1F1C); 7 | // Monokai theme 8 | static const symbols = Color(0xFFF8F8F2); 9 | static const keywords = Color(0xFFE05276); 10 | static const identifiers = Color(0xFF8AD4ED); 11 | static const strings = Color(0xFFE4DC7A); 12 | static const numbers = Color(0xFFA585FC); 13 | static const comments = Color(0xFF878470); 14 | static const functions = Color(0xFFB5DE3E); 15 | static const operators = Color(0xFFE05276); 16 | static const booleans = Color(0xFFA585FC); 17 | static const debugValues = Color(0xFFECA137); 18 | static const debugError = Color(0xFFEE8F73); 19 | static const debugErrorOverlay = Color(0x99775146); 20 | static const error = Colors.redAccent; 21 | } 22 | -------------------------------------------------------------------------------- /lib/test/misc/precedence.lox: -------------------------------------------------------------------------------- 1 | // * has higher precedence than +. 2 | print 2 + 3 * 4; // expect: 14 3 | 4 | // * has higher precedence than -. 5 | print 20 - 3 * 4; // expect: 8 6 | 7 | // / has higher precedence than +. 8 | print 2 + 6 / 3; // expect: 4 9 | 10 | // / has higher precedence than -. 11 | print 2 - 6 / 3; // expect: 0 12 | 13 | // < has higher precedence than ==. 14 | print false == 2 < 1; // expect: true 15 | 16 | // > has higher precedence than ==. 17 | print false == 1 > 2; // expect: true 18 | 19 | // <= has higher precedence than ==. 20 | print false == 2 <= 1; // expect: true 21 | 22 | // >= has higher precedence than ==. 23 | print false == 1 >= 2; // expect: true 24 | 25 | // 1 - 1 is not space-sensitive. 26 | print 1 - 1; // expect: 0 27 | print 1 -1; // expect: 0 28 | print 1- 1; // expect: 0 29 | print 1-1; // expect: 0 30 | 31 | // Using () for grouping. 32 | print (2 * (6 - (2 + 2))); // expect: 4 33 | -------------------------------------------------------------------------------- /editor/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 9.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /editor/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | **/ios/Flutter/.last_build_id 26 | .dart_tool/ 27 | .flutter-plugins 28 | .flutter-plugins-dependencies 29 | .packages 30 | .pub-cache/ 31 | .pub/ 32 | /build/ 33 | 34 | # Web related 35 | lib/generated_plugin_registrant.dart 36 | 37 | # Symbolication related 38 | app.*.symbols 39 | 40 | # Obfuscation related 41 | app.*.map.json 42 | 43 | # Android Studio will place build artifacts here 44 | /android/app/debug 45 | /android/app/profile 46 | /android/app/release 47 | -------------------------------------------------------------------------------- /lib/test/for/syntax.lox: -------------------------------------------------------------------------------- 1 | // Single-expression body. 2 | for (var c = 0; c < 3;) print c = c + 1; 3 | // expect: 1 4 | // expect: 2 5 | // expect: 3 6 | 7 | // Block body. 8 | for (var a = 0; a < 3; a = a + 1) { 9 | print a; 10 | } 11 | // expect: 0 12 | // expect: 1 13 | // expect: 2 14 | 15 | // No clauses. 16 | fun foo() { 17 | for (;;) return "done"; 18 | } 19 | print foo(); // expect: done 20 | 21 | // No variable. 22 | var i = 0; 23 | for (; i < 2; i = i + 1) print i; 24 | // expect: 0 25 | // expect: 1 26 | 27 | // No condition. 28 | fun bar() { 29 | for (var i = 0;; i = i + 1) { 30 | print i; 31 | if (i >= 2) return; 32 | } 33 | } 34 | bar(); 35 | // expect: 0 36 | // expect: 1 37 | // expect: 2 38 | 39 | // No increment. 40 | for (var i = 0; i < 2;) { 41 | print i; 42 | i = i + 1; 43 | } 44 | // expect: 0 45 | // expect: 1 46 | 47 | // Statement bodies. 48 | for (; false;) if (true) 1; else 2; 49 | for (; false;) while (true) 1; 50 | for (; false;) for (;;) 1; 51 | -------------------------------------------------------------------------------- /lib/test/method/arity.lox: -------------------------------------------------------------------------------- 1 | class Foo { 2 | method0() { return "no args"; } 3 | method1(a) { return a; } 4 | method2(a, b) { return a + b; } 5 | method3(a, b, c) { return a + b + c; } 6 | method4(a, b, c, d) { return a + b + c + d; } 7 | method5(a, b, c, d, e) { return a + b + c + d + e; } 8 | method6(a, b, c, d, e, f) { return a + b + c + d + e + f; } 9 | method7(a, b, c, d, e, f, g) { return a + b + c + d + e + f + g; } 10 | method8(a, b, c, d, e, f, g, h) { return a + b + c + d + e + f + g + h; } 11 | } 12 | 13 | var foo = Foo(); 14 | print foo.method0(); // expect: no args 15 | print foo.method1(1); // expect: 1 16 | print foo.method2(1, 2); // expect: 3 17 | print foo.method3(1, 2, 3); // expect: 6 18 | print foo.method4(1, 2, 3, 4); // expect: 10 19 | print foo.method5(1, 2, 3, 4, 5); // expect: 15 20 | print foo.method6(1, 2, 3, 4, 5, 6); // expect: 21 21 | print foo.method7(1, 2, 3, 4, 5, 6, 7); // expect: 28 22 | print foo.method8(1, 2, 3, 4, 5, 6, 7, 8); // expect: 36 23 | -------------------------------------------------------------------------------- /editor/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /editor/android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Bertrand Bevillard 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /lib/error.dart: -------------------------------------------------------------------------------- 1 | import 'package:dlox/scanner.dart'; 2 | 3 | import 'debug.dart'; 4 | 5 | class LangError { 6 | final String type; 7 | final Token token; 8 | int line; 9 | final String msg; 10 | 11 | LangError(this.type, this.msg, {this.line, this.token}); 12 | 13 | void dump(Debug debug) { 14 | debug.stdwriteln(toString()); 15 | } 16 | 17 | @override 18 | String toString() { 19 | final buf = StringBuffer(); 20 | if (token != null) { 21 | buf.write('[${token.loc.i + 1}:${token.loc.j}] $type error'); 22 | if (token.type == TokenType.EOF) { 23 | buf.write(' at end'); 24 | } else if (token.type == TokenType.ERROR) { 25 | // Nothing. 26 | } else { 27 | buf.write(' at \'${token.str}\''); 28 | } 29 | } else if (line != null) { 30 | buf.write('[$line] $type error'); 31 | } else { 32 | buf.write('$type error'); 33 | } 34 | buf.write(': $msg'); 35 | return buf.toString(); 36 | } 37 | } 38 | 39 | class CompilerError extends LangError { 40 | CompilerError(Token token, String msg) 41 | : super('Compile', msg, token: token, line: token.loc.i); 42 | } 43 | 44 | class RuntimeError extends LangError { 45 | final RuntimeError link; 46 | 47 | RuntimeError(int line, String msg, {this.link}) 48 | : super('Runtime', msg, line: line); 49 | } 50 | -------------------------------------------------------------------------------- /editor/lib/widgets/progress_button.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class ProgressButton extends StatelessWidget { 4 | final IconData icon; 5 | final double size; 6 | final Color color; 7 | final bool loading; 8 | final Function onTap; 9 | final bool disabled; 10 | 11 | ProgressButton({ 12 | this.icon, 13 | this.loading, 14 | this.onTap, 15 | this.disabled = false, 16 | this.color = Colors.white, 17 | this.size = 28.0, 18 | }); 19 | 20 | @override 21 | Widget build(BuildContext context) { 22 | final button = IconButton( 23 | color: color, 24 | disabledColor: Colors.grey.shade700, 25 | constraints: BoxConstraints(), 26 | padding: EdgeInsets.zero, 27 | icon: Icon(icon), 28 | onPressed: !disabled ? onTap : null, 29 | ); 30 | final progressChild = loading 31 | ? CircularProgressIndicator( 32 | valueColor: AlwaysStoppedAnimation(color), 33 | strokeWidth: 2, 34 | ) 35 | : SizedBox.shrink(); 36 | final progress = SizedBox( 37 | width: size, 38 | height: size, 39 | child: progressChild, 40 | ); 41 | return Stack( 42 | alignment: Alignment.center, 43 | children: [ 44 | progress, 45 | Container(child: button), 46 | ], 47 | ); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'dart:io'; 3 | import 'package:dlox/scanner.dart'; 4 | import 'package:dlox/vm.dart'; 5 | import 'compiler.dart'; 6 | 7 | void repl() { 8 | final vm = VM(); 9 | while (true) { 10 | stdout.write('> '); 11 | final line = stdin.readLineSync(encoding: Encoding.getByName('utf-8')); 12 | if (line == null) break; 13 | final tokens = Scanner.scan(line + '\n'); 14 | final compilerResult = Compiler.compile(tokens); 15 | if (compilerResult.errors.isNotEmpty) continue; 16 | final globals = Map.fromEntries(vm.globals.data.entries); 17 | vm.setFunction(compilerResult, FunctionParams(globals: globals)); 18 | vm.run(); 19 | } 20 | } 21 | 22 | String readFile(String path) { 23 | return File(path).readAsStringSync(); 24 | } 25 | 26 | void runFile(String path) { 27 | final vm = VM(); 28 | final source = readFile(path); 29 | final tokens = Scanner.scan( 30 | source, 31 | ); 32 | final compilerResult = Compiler.compile(tokens); 33 | if (compilerResult.errors.isNotEmpty) exit(65); 34 | vm.setFunction(compilerResult, FunctionParams()); 35 | final intepreterResult = vm.run(); 36 | if (intepreterResult.errors.isNotEmpty) exit(70); 37 | } 38 | 39 | void main(List args) async { 40 | if (args.isEmpty) { 41 | repl(); 42 | } else if (args.length == 1) { 43 | runFile(args[0]); 44 | } else { 45 | print('Usage: dart main.dart [path]'); 46 | exit(64); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /lib/chunk.dart: -------------------------------------------------------------------------------- 1 | import 'package:dlox/scanner.dart'; 2 | 3 | enum OpCode { 4 | CONSTANT, 5 | NIL, 6 | TRUE, 7 | FALSE, 8 | POP, 9 | GET_LOCAL, 10 | SET_LOCAL, 11 | GET_GLOBAL, 12 | DEFINE_GLOBAL, 13 | SET_GLOBAL, 14 | GET_UPVALUE, 15 | SET_UPVALUE, 16 | GET_PROPERTY, 17 | SET_PROPERTY, 18 | GET_SUPER, 19 | EQUAL, 20 | GREATER, 21 | LESS, 22 | ADD, 23 | SUBTRACT, 24 | MULTIPLY, 25 | DIVIDE, 26 | POW, 27 | MOD, 28 | NOT, 29 | NEGATE, 30 | PRINT, 31 | JUMP, 32 | JUMP_IF_FALSE, 33 | LOOP, 34 | CALL, 35 | INVOKE, 36 | SUPER_INVOKE, 37 | CLOSURE, 38 | CLOSE_UPVALUE, 39 | RETURN, 40 | CLASS, 41 | INHERIT, 42 | METHOD, 43 | LIST_INIT, 44 | LIST_INIT_RANGE, 45 | MAP_INIT, 46 | CONTAINER_GET, 47 | CONTAINER_SET, 48 | CONTAINER_GET_RANGE, 49 | CONTAINER_ITERATE, 50 | } 51 | 52 | class Chunk { 53 | final List code = []; 54 | final List constants = []; 55 | final _constantMap = {}; 56 | // Trace information 57 | final List lines = []; 58 | 59 | Chunk(); 60 | 61 | int get count => code.length; 62 | 63 | void write(int byte, Token token) { 64 | code.add(byte); 65 | lines.add(token.loc.i); 66 | } 67 | 68 | int addConstant(Object value) { 69 | final idx = _constantMap[value]; 70 | if (idx != null) return idx; 71 | // Add entry 72 | constants.add(value); 73 | _constantMap[value] = constants.length - 1; 74 | return constants.length - 1; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /editor/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def flutter_root 14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) 15 | unless File.exist?(generated_xcode_build_settings_path) 16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" 17 | end 18 | 19 | File.foreach(generated_xcode_build_settings_path) do |line| 20 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 21 | return matches[1].strip if matches 22 | end 23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" 24 | end 25 | 26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 27 | 28 | flutter_ios_podfile_setup 29 | 30 | target 'Runner' do 31 | use_frameworks! 32 | use_modular_headers! 33 | 34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 35 | end 36 | 37 | post_install do |installer| 38 | installer.pods_project.targets.each do |target| 39 | flutter_additional_ios_build_settings(target) 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /editor/lib/widgets/flushbar.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | enum FlushbarType { 4 | INFO, 5 | WARNING, 6 | } 7 | 8 | class Flushbar { 9 | static void show( 10 | BuildContext context, 11 | String msg, { 12 | FlushbarType type = FlushbarType.INFO, 13 | }) { 14 | final icon = 15 | type == FlushbarType.INFO ? Icons.info_outline : Icons.error_outline; 16 | final color = 17 | type == FlushbarType.INFO ? Colors.blueAccent : Colors.redAccent; 18 | ScaffoldMessenger.of(context).removeCurrentSnackBar(); 19 | ScaffoldMessenger.of(context).showSnackBar( 20 | SnackBar( 21 | content: Container( 22 | padding: EdgeInsets.symmetric(horizontal: 16.0, vertical: 12.0), 23 | margin: EdgeInsets.all(0.0), 24 | decoration: BoxDecoration( 25 | color: Colors.grey.shade900, 26 | borderRadius: BorderRadius.all(Radius.circular(8.0)), 27 | ), 28 | child: Row( 29 | children: [ 30 | Icon(icon, color: color), 31 | SizedBox(width: 8.0), 32 | Flexible( 33 | child: Text(msg, style: TextStyle(fontSize: 16.0)), 34 | ), 35 | ], 36 | ), 37 | ), 38 | width: 600, 39 | behavior: SnackBarBehavior.floating, 40 | backgroundColor: Colors.transparent, 41 | elevation: 0.0, 42 | // padding: EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0), 43 | ), 44 | ); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /editor/web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | editor 30 | 31 | 32 | 33 | 36 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /editor/ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /editor/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | editor 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UIViewControllerBasedStatusBarAppearance 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /lib/parser.dart: -------------------------------------------------------------------------------- 1 | import 'package:dlox/debug.dart'; 2 | import 'package:dlox/scanner.dart'; 3 | 4 | import 'error.dart'; 5 | 6 | class Parser { 7 | final List tokens; 8 | final List errors = []; 9 | Token current; 10 | Token previous; 11 | Token secondPrevious; 12 | int currentIdx = 0; 13 | bool panicMode = false; 14 | Debug debug; 15 | 16 | Parser(this.tokens, {bool silent = false}) { 17 | debug = Debug(silent); 18 | } 19 | 20 | void errorAt(Token token, String message) { 21 | if (panicMode) return; 22 | panicMode = true; 23 | final error = CompilerError(token, message); 24 | errors.add(error); 25 | error.dump(debug); 26 | } 27 | 28 | void error(String message) { 29 | errorAt(previous, message); 30 | } 31 | 32 | void errorAtCurrent(String message) { 33 | errorAt(current, message); 34 | } 35 | 36 | void advance() { 37 | secondPrevious = previous; // TODO: is it needed? 38 | previous = current; 39 | while (currentIdx < tokens.length) { 40 | current = tokens[currentIdx++]; 41 | // Skip invalid tokens 42 | if (current.type == TokenType.ERROR) { 43 | errorAtCurrent(current.str); 44 | } else if (current.type != TokenType.COMMENT) break; 45 | } 46 | } 47 | 48 | void consume(TokenType type, String message) { 49 | if (current.type == type) { 50 | advance(); 51 | return; 52 | } 53 | errorAtCurrent(message); 54 | } 55 | 56 | bool check(TokenType type) { 57 | return current.type == type; 58 | } 59 | 60 | bool matchPair(TokenType first, TokenType second) { 61 | if (!check(first) || 62 | currentIdx >= tokens.length || 63 | tokens[currentIdx].type != second) return false; 64 | advance(); 65 | advance(); 66 | return true; 67 | } 68 | 69 | bool match(TokenType type) { 70 | if (!check(type)) return false; 71 | advance(); 72 | return true; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /editor/lib/widgets/toggle_button.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class ToggleButton extends StatelessWidget { 4 | final Function leftToggle; 5 | final Function rightToggle; 6 | final bool leftEnabled; 7 | final bool rightEnabled; 8 | final IconData leftIcon; 9 | final IconData rightIcon; 10 | 11 | const ToggleButton({ 12 | Key key, 13 | this.leftToggle, 14 | this.rightToggle, 15 | this.leftEnabled, 16 | this.rightEnabled, 17 | this.leftIcon, 18 | this.rightIcon, 19 | }) : super(key: key); 20 | 21 | Widget _buildBtn(bool left) { 22 | final enabled = left ? leftEnabled : rightEnabled; 23 | final action = left ? leftToggle : rightToggle; 24 | final icon = left ? leftIcon : rightIcon; 25 | final color = enabled ? Colors.grey.shade800 : Colors.transparent; 26 | final iconColor = enabled ? Colors.white : Colors.grey; 27 | return RawMaterialButton( 28 | materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, 29 | padding: EdgeInsets.symmetric(vertical: 4.0, horizontal: 8.0), 30 | onPressed: action, 31 | constraints: BoxConstraints(minWidth: 0, minHeight: 0), 32 | child: Icon(icon, color: iconColor), 33 | fillColor: color, 34 | shape: RoundedRectangleBorder( 35 | side: BorderSide(color: Colors.grey.shade800), 36 | borderRadius: BorderRadius.only( 37 | topLeft: Radius.circular(left ? 8.0 : 0.0), 38 | bottomLeft: Radius.circular(left ? 8.0 : 0.0), 39 | topRight: Radius.circular(!left ? 8.0 : 0.0), 40 | bottomRight: Radius.circular(!left ? 8.0 : 0.0), 41 | ), 42 | ), 43 | ); 44 | } 45 | 46 | @override 47 | Widget build(BuildContext context) { 48 | return Padding( 49 | padding: const EdgeInsets.all(8.0), 50 | child: Row(children: [ 51 | _buildBtn(true), 52 | // VerticalDivider(width: 0.5), 53 | _buildBtn(false), 54 | ]), 55 | ); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /editor/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | android { 29 | compileSdkVersion 29 30 | 31 | sourceSets { 32 | main.java.srcDirs += 'src/main/kotlin' 33 | } 34 | 35 | lintOptions { 36 | disable 'InvalidPackage' 37 | } 38 | 39 | defaultConfig { 40 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 41 | applicationId "com.example.editor" 42 | minSdkVersion 16 43 | targetSdkVersion 29 44 | versionCode flutterVersionCode.toInteger() 45 | versionName flutterVersionName 46 | } 47 | 48 | buildTypes { 49 | release { 50 | // TODO: Add your own signing config for the release build. 51 | // Signing with the debug keys for now, so `flutter run --release` works. 52 | signingConfig signingConfigs.debug 53 | } 54 | } 55 | } 56 | 57 | flutter { 58 | source '../..' 59 | } 60 | 61 | dependencies { 62 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 63 | } 64 | -------------------------------------------------------------------------------- /editor/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 13 | 17 | 21 | 26 | 30 | 31 | 32 | 33 | 34 | 35 | 37 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /editor/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: editor 2 | description: dlox editor 3 | publish_to: "none" 4 | 5 | version: 1.0.0+1 6 | 7 | environment: 8 | sdk: ">=2.7.0 <3.0.0" 9 | 10 | dependencies: 11 | flutter: 12 | sdk: flutter 13 | cupertino_icons: ^1.0.0 14 | flutter_icons: ^1.1.0 15 | flutter_parsed_text: ^2.1.0 16 | provider: ^5.0.0 17 | url_launcher: ^6.0.2 18 | sprintf: ^6.0.0 # WHY? 19 | code_text_field: ^1.0.0-7 20 | dlox: 21 | path: ../ 22 | 23 | 24 | dev_dependencies: 25 | flutter_test: 26 | sdk: flutter 27 | 28 | # For information on the generic Dart part of this file, see the 29 | # following page: https://dart.dev/tools/pub/pubspec 30 | 31 | # The following section is specific to Flutter. 32 | flutter: 33 | uses-material-design: true 34 | assets: 35 | - assets/snippets/ 36 | fonts: 37 | - family: SourceCode 38 | fonts: 39 | - asset: assets/fonts/sourceCode/SourceCodePro-Black.ttf 40 | weight: 900 41 | - asset: assets/fonts/sourceCode/SourceCodePro-BlackItalic.ttf 42 | style: italic 43 | weight: 900 44 | - asset: assets/fonts/sourceCode/SourceCodePro-Bold.ttf 45 | weight: 700 46 | - asset: assets/fonts/sourceCode/SourceCodePro-BoldItalic.ttf 47 | style: italic 48 | weight: 700 49 | - asset: assets/fonts/sourceCode/SourceCodePro-SemiBold.ttf 50 | weight: 600 51 | - asset: assets/fonts/sourceCode/SourceCodePro-SemiBoldItalic.ttf 52 | style: italic 53 | weight: 600 54 | - asset: assets/fonts/sourceCode/SourceCodePro-Medium.ttf 55 | weight: 500 56 | - asset: assets/fonts/sourceCode/SourceCodePro-MediumItalic.ttf 57 | style: italic 58 | weight: 500 59 | - asset: assets/fonts/sourceCode/SourceCodePro-Regular.ttf 60 | weight: 400 61 | - asset: assets/fonts/sourceCode/SourceCodePro-Italic.ttf 62 | style: italic 63 | weight: 400 64 | - asset: assets/fonts/sourceCode/SourceCodePro-Light.ttf 65 | weight: 300 66 | - asset: assets/fonts/sourceCode/SourceCodePro-LightItalic.ttf 67 | style: italic 68 | weight: 300 69 | - asset: assets/fonts/sourceCode/SourceCodePro-ExtraLight.ttf 70 | weight: 200 71 | - asset: assets/fonts/sourceCode/SourceCodePro-ExtraLightItalic.ttf 72 | style: italic 73 | weight: 200 74 | -------------------------------------------------------------------------------- /editor/ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /editor/lib/lox_mode.dart: -------------------------------------------------------------------------------- 1 | // Derived from dart.dart 2 | 3 | import 'package:highlight/src/mode.dart'; 4 | import 'package:highlight/src/common_modes.dart'; 5 | 6 | final lox = Mode(refs: { 7 | '~contains~0~variants~4~contains~2': Mode( 8 | className: "subst", 9 | variants: [Mode(begin: "\\\${", end: "}")], 10 | keywords: "true false nil this super", 11 | contains: [C_NUMBER_MODE, Mode(ref: '~contains~0')]), 12 | '~contains~0~variants~4~contains~1': 13 | Mode(className: "subst", variants: [Mode(begin: "\\\$[A-Za-z0-9_]+")]), 14 | '~contains~0': Mode(className: "string", variants: [ 15 | Mode(begin: "r'''", end: "'''"), 16 | Mode(begin: "r\"\"\"", end: "\"\"\""), 17 | Mode(begin: "r'", end: "'", illegal: "\\n"), 18 | Mode(begin: "r\"", end: "\"", illegal: "\\n"), 19 | Mode(begin: "'''", end: "'''", contains: [ 20 | BACKSLASH_ESCAPE, 21 | Mode(ref: '~contains~0~variants~4~contains~1'), 22 | Mode(ref: '~contains~0~variants~4~contains~2') 23 | ]), 24 | Mode(begin: "\"\"\"", end: "\"\"\"", contains: [ 25 | BACKSLASH_ESCAPE, 26 | Mode(ref: '~contains~0~variants~4~contains~1'), 27 | Mode(ref: '~contains~0~variants~4~contains~2') 28 | ]), 29 | Mode(begin: "'", end: "'", illegal: "\\n", contains: [ 30 | BACKSLASH_ESCAPE, 31 | Mode(ref: '~contains~0~variants~4~contains~1'), 32 | Mode(ref: '~contains~0~variants~4~contains~2') 33 | ]), 34 | Mode(begin: "\"", end: "\"", illegal: "\\n", contains: [ 35 | BACKSLASH_ESCAPE, 36 | Mode(ref: '~contains~0~variants~4~contains~1'), 37 | Mode(ref: '~contains~0~variants~4~contains~2') 38 | ]) 39 | ]), 40 | }, keywords: { 41 | "keyword": "class else false for if nil return super this true var while fun in print", 42 | "built_in": "" 43 | }, contains: [ 44 | Mode(ref: '~contains~0'), 45 | Mode(className: "comment", begin: "/\\*\\*", end: "\\*/", contains: [ 46 | PHRASAL_WORDS_MODE, 47 | Mode( 48 | className: "doctag", 49 | begin: "(?:TODO|FIXME|NOTE|BUG|XXX):", 50 | relevance: 0) 51 | ], subLanguage: [ 52 | "markdown" 53 | ]), 54 | Mode(className: "comment", begin: "///+\\s*", end: "\$", contains: [ 55 | Mode(subLanguage: ["markdown"], begin: ".", end: "\$"), 56 | PHRASAL_WORDS_MODE, 57 | Mode( 58 | className: "doctag", 59 | begin: "(?:TODO|FIXME|NOTE|BUG|XXX):", 60 | relevance: 0) 61 | ]), 62 | C_LINE_COMMENT_MODE, 63 | C_BLOCK_COMMENT_MODE, 64 | Mode( 65 | className: "class", 66 | beginKeywords: "class interface", 67 | end: "{", 68 | excludeEnd: true, 69 | contains: [ 70 | Mode(beginKeywords: "extends implements"), 71 | UNDERSCORE_TITLE_MODE 72 | ]), 73 | C_NUMBER_MODE, 74 | Mode(className: "meta", begin: "@[A-Za-z]+"), 75 | Mode(begin: "=>") 76 | ]); 77 | -------------------------------------------------------------------------------- /lib/object.dart: -------------------------------------------------------------------------------- 1 | 2 | import 'package:dlox/chunk.dart'; 3 | import 'package:dlox/table.dart'; 4 | import 'package:dlox/value.dart'; 5 | import 'native.dart'; 6 | import 'native_classes.dart'; 7 | 8 | class ObjNative { 9 | String name; 10 | int arity; 11 | NativeFunction fn; 12 | 13 | ObjNative(this.name, this.arity, this.fn); 14 | } 15 | 16 | class ObjFunction { 17 | final Chunk chunk = Chunk(); 18 | int arity = 0; 19 | int upvalueCount = 0; 20 | String name; 21 | 22 | ObjFunction(); 23 | } 24 | 25 | class ObjUpvalue { 26 | int location; 27 | Object closed = Nil; 28 | ObjUpvalue next; 29 | 30 | ObjUpvalue(this.location); 31 | } 32 | 33 | class ObjClosure { 34 | ObjFunction function; 35 | List upvalues; 36 | int upvalueCount; 37 | 38 | ObjClosure(this.function) { 39 | upvalues = List(function.upvalueCount); 40 | upvalueCount = function.upvalueCount; 41 | } 42 | } 43 | 44 | class ObjClass { 45 | String name; 46 | Table methods = Table(); 47 | 48 | ObjClass(this.name); 49 | } 50 | 51 | class ObjInstance { 52 | String klassName; // For dynamic class lookup 53 | ObjClass klass; 54 | Table fields = Table(); 55 | 56 | ObjInstance({this.klass, this.klassName}); 57 | } 58 | 59 | class ObjBoundMethod { 60 | Object receiver; 61 | ObjClosure method; 62 | 63 | ObjBoundMethod(this.receiver, this.method); 64 | } 65 | 66 | int hashString(String key) { 67 | var hash = 2166136261; 68 | for (var i = 0; i < key.length; i++) { 69 | hash ^= key.codeUnitAt(i); 70 | hash *= 16777619; 71 | } 72 | return hash; 73 | } 74 | 75 | String functionToString(ObjFunction function) { 76 | if (function.name == null) { 77 | return '