├── .github └── workflows │ └── go.yml ├── .gitignore ├── .vscode ├── c_cpp_properties.json └── settings.json ├── LICENSE ├── README.md ├── binder ├── binder.go ├── boundprogram.go ├── conversion.go ├── gloablscope.go └── scope.go ├── builtins ├── README.md ├── builtin-functions.go ├── builtin-type-functions.go └── builtin-types.go ├── cli.go ├── emitter ├── README.md ├── builtin-functions.go ├── c-adapter.go ├── comment.go ├── debug.go ├── emitter.go ├── module-reader.go └── types.go ├── evaluator ├── README.md └── evaluator.go ├── go.mod ├── go.sum ├── irtools └── module-reader.go ├── langserverinterface ├── interface.go ├── mapper.go └── meanings.go ├── lexer ├── README.md ├── lexer.go └── token.go ├── link_lin.sh ├── lowerer ├── README.md └── lowerer.go ├── main.go ├── mod.ll ├── nodes ├── README.md ├── boundnodes │ ├── README.md │ ├── boundBinaryOperator.go │ ├── boundUnaryOperator.go │ ├── boundnode.go │ ├── expr-boundArrayAccessExpression.go │ ├── expr-boundArrayAssignmentExpression.go │ ├── expr-boundAssignmentExpression.go │ ├── expr-boundBinaryExpression.go │ ├── expr-boundCallExpression.go │ ├── expr-boundClassCallExpression.go │ ├── expr-boundClassFieldAccessExpression.go │ ├── expr-boundClassFieldAssignmentExpression.go │ ├── expr-boundConversionExpression.go │ ├── expr-boundDereferenceExpression.go │ ├── expr-boundEnumExpression.go │ ├── expr-boundErrorExpression.go │ ├── expr-boundFunctionExpression.go │ ├── expr-boundInternalValueExpression.go │ ├── expr-boundLambdaExpression.go │ ├── expr-boundLiteralExpression.go │ ├── expr-boundMakeArrayExpression.go │ ├── expr-boundMakeExpression.go │ ├── expr-boundMakeStructExpression.go │ ├── expr-boundPackageCallExpression.go │ ├── expr-boundReferenceExpression.go │ ├── expr-boundThisExpression.go │ ├── expr-boundTypeCallExpression.go │ ├── expr-boundUnaryExpression.go │ ├── expr-boundVariableExpression.go │ ├── expr-ternaryExpression.go │ ├── stmt-boundBlockStatement.go │ ├── stmt-boundConditionalGotoStatement.go │ ├── stmt-boundExpressionStatement.go │ ├── stmt-boundForStatement.go │ ├── stmt-boundFromToStatement.go │ ├── stmt-boundGotoStatement.go │ ├── stmt-boundIfStatement.go │ ├── stmt-boundLabelStatement.go │ ├── stmt-boundReturnStatement.go │ ├── stmt-boundVariableDeclaration.go │ └── stmt-boundWhileStatement.go ├── clause-elseClause.go ├── clause-typeClause.go ├── expr-arrayAccessExpression.go ├── expr-arrayAssignmentExpression.go ├── expr-assignmentExpression.go ├── expr-binaryExpression.go ├── expr-callExpression.go ├── expr-classFieldAccessEpxression.go ├── expr-classFieldAssignmentEpxression.go ├── expr-dereferenceExpression.go ├── expr-lambdaExpression.go ├── expr-literalExpression.go ├── expr-makeArrayExpression.go ├── expr-makeExpression.go ├── expr-makeStructExpression.go ├── expr-nameExpression.go ├── expr-packageCallExpression.go ├── expr-parenthesizedExpression.go ├── expr-referenceExpression.go ├── expr-ternaryExpression.go ├── expr-thisExpression.go ├── expr-typeCallEpxression.go ├── expr-unaryExpression.go ├── expr-variableEditorExpression.go ├── node-classDeclarationMember.go ├── node-enumDeclarationMember.go ├── node-externalFunctionDeclarationMember.go ├── node-functionDeclarationMember.go ├── node-globalStatementMember.go ├── node-packageAliasMember.go ├── node-packageReferenceMember.go ├── node-packageUseMember.go ├── node-parameterNode.go ├── node-structDeclarationMember.go ├── stmt-blockStatement.go ├── stmt-breakStatement.go ├── stmt-continueStatement.go ├── stmt-expressionStatement.go ├── stmt-forStatement.go ├── stmt-fromToStatement.go ├── stmt-ifStatement.go ├── stmt-returnStatement.go ├── stmt-variableDeclaration.go ├── stmt-whileStatement.go └── syntaxnode.go ├── packager └── packager.go ├── packages ├── Dictionary.ll ├── Dictionary │ ├── LICENSE │ └── README.md ├── konsole.ll ├── pkginfo.db └── sys.bc ├── parser ├── README.md └── parser.go ├── preprocessor └── preprocessor.go ├── print ├── error.go ├── print.go └── textspan.go ├── program.ll ├── rps ├── rules └── rules.go ├── run_lin.sh ├── symbols ├── README.md ├── classSymbol.go ├── enumSymbol.go ├── functionSymbol.go ├── globalVariableSymbol.go ├── localVariableSymbol.go ├── packageSymbol.go ├── parameterSymbol.go ├── structSymbol.go ├── symbol.go ├── typeFunctionSymbol.go └── typeSymbol.go ├── systemlib ├── exceptions.bc ├── exceptions.c ├── exceptions.h ├── objects.bc ├── objects.c ├── objects.h ├── objects.ll ├── syslib_compile_lin.sh ├── systemlib_lin.bc └── systemlib_lin.ll ├── systempacks └── sys.c └── tests ├── arrayTest.rct ├── arrayTest2.rct ├── bitshift.rct ├── byteTest.rct ├── classTest.rct ├── classlambda.rct ├── customPackageTest.rct ├── dicTest.rct ├── exceptionTest.rct ├── fib.rct ├── helloWorld.rct ├── konsoleTest.rct ├── lambda.rct ├── lowlevelrect.rct ├── multifile ├── one.rct └── two.rct ├── packageTest.rct ├── preproc.rct ├── primeBenchmark.rct ├── stringBenchmark.rct ├── sysTest.rct ├── test1.rct ├── threadTest.rct └── wedoalittlemeta.rct /.github/workflows/go.yml: -------------------------------------------------------------------------------- 1 | name: Go 2 | 3 | on: 4 | push: 5 | pull_request: 6 | branches: [ main ] 7 | 8 | jobs: 9 | 10 | build: 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - uses: actions/checkout@v2 15 | 16 | - name: Set up Go 17 | uses: actions/setup-go@v2 18 | with: 19 | go-version: 1.17 20 | 21 | - name: Build 22 | run: go build -v . 23 | 24 | - name: Run 25 | run: go run -v . 26 | 27 | - name: Test 28 | run: go test -v . 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # executables 2 | rgoc 3 | ReCT-Go-Compiler 4 | 5 | # compilation files 6 | out.bc 7 | out.ll 8 | program.bc 9 | program 10 | a.out 11 | 12 | # annoy configs 13 | .replit 14 | .gitpod 15 | *.toml 16 | 17 | # idea metadata 18 | **.idea/** -------------------------------------------------------------------------------- /.vscode/c_cpp_properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "configurations": [ 3 | { 4 | "name": "Linux", 5 | "includePath": [ 6 | "${workspaceFolder}/**" 7 | ], 8 | "defines": [], 9 | "compilerPath": "/usr/bin/clang", 10 | "cStandard": "c17", 11 | "cppStandard": "c++14", 12 | "intelliSenseMode": "linux-clang-x64" 13 | } 14 | ], 15 | "version": 4 16 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "array": "c", 4 | "hash_map": "c", 5 | "deque": "c", 6 | "forward_list": "c", 7 | "list": "c", 8 | "string": "c", 9 | "unordered_map": "c", 10 | "unordered_set": "c", 11 | "vector": "c", 12 | "string_view": "c", 13 | "initializer_list": "c", 14 | "valarray": "c", 15 | "chrono": "c", 16 | "variant": "c", 17 | "string.h": "c", 18 | "math.h": "c", 19 | "optional": "c", 20 | "istream": "c", 21 | "ostream": "c", 22 | "ratio": "c", 23 | "system_error": "c", 24 | "functional": "c", 25 | "tuple": "c", 26 | "type_traits": "c", 27 | "utility": "c", 28 | "bitset": "c", 29 | "sstream": "c", 30 | "execinfo.h": "c", 31 | "arc.h": "c", 32 | "compare": "c", 33 | "__hash_table": "c", 34 | "__tree": "c", 35 | "__tuple": "c", 36 | "cstddef": "c", 37 | "limits": "c", 38 | "algorithm": "c", 39 | "__bit_reference": "c", 40 | "map": "c", 41 | "set": "c", 42 | "objects.h": "c", 43 | "exceptions.h": "c" 44 | } 45 | } -------------------------------------------------------------------------------- /binder/scope.go: -------------------------------------------------------------------------------- 1 | package binder 2 | 3 | import "github.com/ReCT-Lang/ReCT-Go-Compiler/symbols" 4 | 5 | type Scope struct { 6 | Parent *Scope 7 | Symbols map[string]symbols.Symbol 8 | } 9 | 10 | func (s *Scope) TryDeclareSymbol(sym symbols.Symbol) bool { 11 | 12 | lookup := s.TryLookupSymbol(sym.SymbolName()) 13 | 14 | if lookup != nil { 15 | return false // symbol already exists 16 | } else { 17 | s.Symbols[sym.SymbolName()] = sym 18 | return true 19 | } 20 | } 21 | 22 | func (s Scope) TryLookupSymbol(name string) symbols.Symbol { 23 | sym, found := s.Symbols[name] 24 | 25 | if found { 26 | return sym 27 | } 28 | 29 | if s.Parent != nil { 30 | return s.Parent.TryLookupSymbol(name) 31 | } 32 | 33 | return nil 34 | } 35 | 36 | func (s Scope) InsertFunctionSymbols(symbols []symbols.FunctionSymbol) { 37 | for _, sym := range symbols { 38 | s.TryDeclareSymbol(sym) 39 | } 40 | } 41 | 42 | func (s Scope) InsertVariableSymbols(symbols []symbols.VariableSymbol) { 43 | for _, sym := range symbols { 44 | s.TryDeclareSymbol(sym) 45 | } 46 | } 47 | 48 | func (s Scope) GetAllFunctions() []symbols.FunctionSymbol { 49 | functions := make([]symbols.FunctionSymbol, 0) 50 | 51 | for _, sym := range s.Symbols { 52 | if sym.SymbolType() == symbols.Function { 53 | functions = append(functions, sym.(symbols.FunctionSymbol)) 54 | } 55 | } 56 | 57 | moreFunctions := make([]symbols.FunctionSymbol, 0) 58 | if s.Parent != nil { 59 | moreFunctions = s.Parent.GetAllFunctions() 60 | } 61 | 62 | functions = append(functions, moreFunctions...) 63 | 64 | return functions 65 | } 66 | 67 | func (s Scope) GetAllVariables() []symbols.VariableSymbol { 68 | variables := make([]symbols.VariableSymbol, 0) 69 | 70 | for _, sym := range s.Symbols { 71 | if sym.SymbolType() == symbols.LocalVariable || 72 | sym.SymbolType() == symbols.GlobalVariable || 73 | sym.SymbolType() == symbols.Parameter { 74 | variables = append(variables, sym.(symbols.VariableSymbol)) 75 | } 76 | } 77 | 78 | moreVariables := make([]symbols.VariableSymbol, 0) 79 | if s.Parent != nil { 80 | moreVariables = s.Parent.GetAllVariables() 81 | } 82 | 83 | variables = append(variables, moreVariables...) 84 | 85 | return variables 86 | } 87 | 88 | func (s Scope) GetAllClasses() []symbols.ClassSymbol { 89 | classes := make([]symbols.ClassSymbol, 0) 90 | 91 | for _, sym := range s.Symbols { 92 | if sym.SymbolType() == symbols.Class { 93 | classes = append(classes, sym.(symbols.ClassSymbol)) 94 | } 95 | } 96 | 97 | moreClasses := make([]symbols.ClassSymbol, 0) 98 | if s.Parent != nil { 99 | moreClasses = s.Parent.GetAllClasses() 100 | } 101 | 102 | classes = append(classes, moreClasses...) 103 | 104 | return classes 105 | } 106 | 107 | func (s Scope) GetAllStructs() []symbols.StructSymbol { 108 | structs := make([]symbols.StructSymbol, 0) 109 | 110 | for _, sym := range s.Symbols { 111 | if sym.SymbolType() == symbols.Struct { 112 | structs = append(structs, sym.(symbols.StructSymbol)) 113 | } 114 | } 115 | 116 | moreStructs := make([]symbols.StructSymbol, 0) 117 | if s.Parent != nil { 118 | moreStructs = s.Parent.GetAllStructs() 119 | } 120 | 121 | structs = append(structs, moreStructs...) 122 | 123 | return structs 124 | } 125 | 126 | func (s Scope) GetAllPackages() []symbols.PackageSymbol { 127 | packages := make([]symbols.PackageSymbol, 0) 128 | 129 | for _, sym := range s.Symbols { 130 | if sym.SymbolType() == symbols.Package { 131 | packages = append(packages, sym.(symbols.PackageSymbol)) 132 | } 133 | } 134 | 135 | morePackages := make([]symbols.PackageSymbol, 0) 136 | if s.Parent != nil { 137 | morePackages = s.Parent.GetAllPackages() 138 | } 139 | 140 | packages = append(packages, morePackages...) 141 | 142 | return packages 143 | } 144 | 145 | // constructor 146 | func CreateScope(parent *Scope) Scope { 147 | return Scope{ 148 | Parent: parent, 149 | Symbols: make(map[string]symbols.Symbol), 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /builtins/README.md: -------------------------------------------------------------------------------- 1 | # ReCT Built-ins 2 | This package contains any datatypes or functions that are built right into ReCT. 3 | These are things like: 4 | 5 | **Datatypes**: `void, bool, int, float, string` 6 | 7 | **Functions**: 8 | | Function | Done | 9 | | ------------- | ------------- | 10 | | `Print()` | :white_check_mark: | 11 | | `Write()` | :white_check_mark: | 12 | | `Input()` | :white_check_mark: | 13 | | `InputKey()` | :white_check_mark: | 14 | | `Clear()` | :white_check_mark: | 15 | | `SetCursor()` | :white_check_mark: | 16 | | `GetSizeX()` | :white_check_mark: | 17 | | `GetSizeY()` | :white_check_mark: | 18 | | `SetSize()` | :white_check_mark: | 19 | | `SetCursorVisible()` | :white_check_mark: | 20 | | `GetCursorVisible()` | :white_check_mark: | 21 | | `Random()` | :white_check_mark: | 22 | | `Sleep()` | :white_check_mark: | 23 | | `Version()` | :white_check_mark: | -------------------------------------------------------------------------------- /builtins/builtin-functions.go: -------------------------------------------------------------------------------- 1 | package builtins 2 | 3 | var ( 4 | // pretty lonely 'round here, huh? 5 | ) 6 | -------------------------------------------------------------------------------- /builtins/builtin-type-functions.go: -------------------------------------------------------------------------------- 1 | package builtins 2 | 3 | import ( 4 | "github.com/ReCT-Lang/ReCT-Go-Compiler/nodes" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/symbols" 6 | ) 7 | 8 | var ( 9 | GetLength = symbols.CreateBuiltInTypeFunctionSymbol( 10 | "GetLength", 11 | []symbols.ParameterSymbol{}, 12 | Int, 13 | nodes.FunctionDeclarationMember{}, 14 | String, 15 | ) 16 | 17 | GetBuffer = symbols.CreateBuiltInTypeFunctionSymbol( 18 | "GetBuffer", 19 | []symbols.ParameterSymbol{}, 20 | symbols.CreateTypeSymbol("pointer", []symbols.TypeSymbol{Byte}, false, false, false, symbols.PackageSymbol{}, nil), 21 | nodes.FunctionDeclarationMember{}, 22 | String, 23 | ) 24 | 25 | GetArrayLength = symbols.CreateBuiltInTypeFunctionSymbol( 26 | "GetLength", 27 | []symbols.ParameterSymbol{}, 28 | Int, 29 | nodes.FunctionDeclarationMember{}, 30 | Array, 31 | ) 32 | 33 | Substring = symbols.CreateBuiltInTypeFunctionSymbol( 34 | "Substring", 35 | []symbols.ParameterSymbol{ 36 | symbols.CreateParameterSymbol("startingIndex", 0, Int), 37 | symbols.CreateParameterSymbol("length", 1, Int), 38 | }, 39 | String, 40 | nodes.FunctionDeclarationMember{}, 41 | String, 42 | ) 43 | 44 | Push = symbols.CreateBuiltInTypeFunctionSymbol( 45 | "Push", 46 | []symbols.ParameterSymbol{ 47 | symbols.CreateParameterSymbol("object", 0, Any), 48 | }, 49 | Void, 50 | nodes.FunctionDeclarationMember{}, 51 | Array, 52 | ) 53 | 54 | PPush = symbols.CreateBuiltInTypeFunctionSymbol( 55 | "PPush", 56 | []symbols.ParameterSymbol{ 57 | symbols.CreateParameterSymbol("element", 0, Identity), 58 | }, 59 | Void, 60 | nodes.FunctionDeclarationMember{}, 61 | Array, 62 | ) 63 | 64 | Start = symbols.CreateBuiltInTypeFunctionSymbol( 65 | "Start", 66 | []symbols.ParameterSymbol{}, 67 | Void, 68 | nodes.FunctionDeclarationMember{}, 69 | Thread, 70 | ) 71 | 72 | Join = symbols.CreateBuiltInTypeFunctionSymbol( 73 | "Join", 74 | []symbols.ParameterSymbol{}, 75 | Void, 76 | nodes.FunctionDeclarationMember{}, 77 | Thread, 78 | ) 79 | 80 | Kill = symbols.CreateBuiltInTypeFunctionSymbol( 81 | "Kill", 82 | []symbols.ParameterSymbol{}, 83 | Void, 84 | nodes.FunctionDeclarationMember{}, 85 | Thread, 86 | ) 87 | 88 | Run = symbols.CreateBuiltInTypeFunctionSymbol( 89 | "Run", 90 | []symbols.ParameterSymbol{}, // ---> these two get filled in on a case by case basis by the binder 91 | Void, // -/ 92 | nodes.FunctionDeclarationMember{}, 93 | Action, 94 | ) 95 | 96 | RunThread = symbols.CreateBuiltInTypeFunctionSymbol( 97 | "RunThread", 98 | []symbols.ParameterSymbol{}, // ---> gets filled in on a case by case basis by the binder 99 | Thread, 100 | nodes.FunctionDeclarationMember{}, 101 | Action, 102 | ) 103 | ) 104 | -------------------------------------------------------------------------------- /builtins/builtin-types.go: -------------------------------------------------------------------------------- 1 | package builtins 2 | 3 | import "github.com/ReCT-Lang/ReCT-Go-Compiler/symbols" 4 | 5 | var ( 6 | Void = symbols.CreateTypeSymbol("void", make([]symbols.TypeSymbol, 0), false, false, false, symbols.PackageSymbol{}, nil) 7 | Bool = symbols.CreateTypeSymbol("bool", make([]symbols.TypeSymbol, 0), false, false, false, symbols.PackageSymbol{}, nil) 8 | Byte = symbols.CreateTypeSymbol("byte", make([]symbols.TypeSymbol, 0), false, false, false, symbols.PackageSymbol{}, nil) 9 | Int = symbols.CreateTypeSymbol("int", make([]symbols.TypeSymbol, 0), false, false, false, symbols.PackageSymbol{}, nil) 10 | UInt = symbols.CreateTypeSymbol("uint", make([]symbols.TypeSymbol, 0), false, false, false, symbols.PackageSymbol{}, nil) 11 | Long = symbols.CreateTypeSymbol("long", make([]symbols.TypeSymbol, 0), false, false, false, symbols.PackageSymbol{}, nil) 12 | ULong = symbols.CreateTypeSymbol("ulong", make([]symbols.TypeSymbol, 0), false, false, false, symbols.PackageSymbol{}, nil) 13 | Float = symbols.CreateTypeSymbol("float", make([]symbols.TypeSymbol, 0), false, false, false, symbols.PackageSymbol{}, nil) 14 | Double = symbols.CreateTypeSymbol("double", make([]symbols.TypeSymbol, 0), false, false, false, symbols.PackageSymbol{}, nil) 15 | String = symbols.CreateTypeSymbol("string", make([]symbols.TypeSymbol, 0), true, false, false, symbols.PackageSymbol{}, nil) 16 | Any = symbols.CreateTypeSymbol("any", make([]symbols.TypeSymbol, 0), true, false, false, symbols.PackageSymbol{}, nil) 17 | 18 | // lambda/functionExpression/action/etc 19 | Action = symbols.CreateTypeSymbol("action", make([]symbols.TypeSymbol, 0), false, false, false, symbols.PackageSymbol{}, nil) 20 | 21 | // threads 22 | Thread = symbols.CreateTypeSymbol("thread", make([]symbols.TypeSymbol, 0), true, false, false, symbols.PackageSymbol{}, nil) 23 | 24 | // generic array types so the emitter has something to work with 25 | Array = symbols.CreateTypeSymbol("array", make([]symbols.TypeSymbol, 0), true, false, false, symbols.PackageSymbol{}, nil) 26 | PArray = symbols.CreateTypeSymbol("parray", make([]symbols.TypeSymbol, 0), true, false, false, symbols.PackageSymbol{}, nil) 27 | 28 | // lazy shortcut 29 | AnyArr = symbols.CreateTypeSymbol("array", []symbols.TypeSymbol{Any}, true, false, false, symbols.PackageSymbol{}, nil) 30 | 31 | // placeholder 32 | Enum = symbols.CreateTypeSymbol("enum", make([]symbols.TypeSymbol, 0), false, false, true, symbols.PackageSymbol{}, nil) 33 | 34 | // spoopy 35 | Pointer = symbols.CreateTypeSymbol("pointer", make([]symbols.TypeSymbol, 0), false, false, false, symbols.PackageSymbol{}, nil) 36 | 37 | // the cursed ones 38 | Error = symbols.CreateTypeSymbol("?", make([]symbols.TypeSymbol, 0), false, false, false, symbols.PackageSymbol{}, nil) 39 | Identity = symbols.CreateTypeSymbol("¯\\_(ツ)_/¯", make([]symbols.TypeSymbol, 0), false, false, false, symbols.PackageSymbol{}, nil) 40 | 41 | Types = []symbols.TypeSymbol{ 42 | Void, Bool, Byte, Int, Long, UInt, ULong, Float, Double, String, Any, Action, Array, PArray, Pointer, Thread, Enum, 43 | } 44 | ) 45 | -------------------------------------------------------------------------------- /emitter/README.md: -------------------------------------------------------------------------------- 1 | # ReCT Emitter 2 | \*Slaps roof of abstract theoretical concept\* 3 | This bad boy can compile lowered and bound ReCT functions to LLVM IR. 4 | 5 | ## Garbage Collection: The Deranged Mumblings of a Grown man at 3 am 6 | So LLVM garbage collection is quite a huge rabbit hole. I've taken some time to look into possibilities of what we could use and how. 7 | **LLVM does not provide a garbage collector** but it does provide some functionality for interfacing 8 | with GCs and also has a few built in GC strategies you can use. 9 | 10 | Our goal is to identify all pointers in the program at rune-time which requires us to check the stack and registers. 11 | LLVM provides support for creating safe-points where GC can happen safely, generating stack maps of object 12 | references the GC may need to update, and creating barriers when storing object references in the heap. 13 | 14 | We can use built-in GC strategies like "The Shadow Stack GC" this strategy has high overhead per function call 15 | as it maintains a "shadow stack" which mirrors the machine stack - Note: a faster way would be to compile stack maps 16 | into the executable. 17 | 18 | LLVM IR has a bunch of features to interface with the GC runtime. LLVM seems to rely on "statepoints". 19 | 20 | ### MMm reddit time 21 | So check out [this reddit post](https://www.reddit.com/r/Compilers/comments/8po0lj/garbage_collection_with_llvm/) from about 4 years ago, dude has the exact same problem, 22 | has a language that can compiler to IR but confused on how GC is put together. Unfortunately, the only decent reply is someone 23 | talking about how plugging in your own GC is hella confusing, and they recommend you use the 24 | [Boehm-Demers-Weiser GC](https://github.com/ivmai/bdwgc) or the [Memory Pool System GC](https://www.ravenbrook.com/project/mps/). 25 | Another reply talks about how they researched the [Boehm-Demers-Weiser GC](https://www.reddit.com/r/Compilers/comments/8po0lj/comment/e0i9dl7/?utm_source=share&utm_medium=web2x&context=3)... 26 | 27 | 28 | Though I really like the idea of us figuring this out on our own, for the time being it may be easier to use a non-llvm approach. 29 | It seems boehm-demer-weider gc is the easiest to set up, so we should just use that for now. 30 | 31 | ### Resources 32 | [LLVM Garbage Collection](https://llvm.org/docs/GarbageCollection.html#goals-and-non-goals) 33 | [LLVM Accurate Garbage Collection](https://releases.llvm.org/3.5.2/docs/GarbageCollection.html) -------------------------------------------------------------------------------- /emitter/builtin-functions.go: -------------------------------------------------------------------------------- 1 | package emitter 2 | 3 | import ( 4 | "github.com/ReCT-Lang/ReCT-Go-Compiler/irtools" 5 | "strings" 6 | 7 | "github.com/llir/llvm/ir" 8 | "github.com/llir/llvm/ir/types" 9 | ) 10 | 11 | func (emt *Emitter) EmitBuiltInFunctions() { 12 | 13 | // link references to the C standard libs 14 | emt.EmitCLibReferences() 15 | 16 | // read the system lib module 17 | module := irtools.ReadModule("./systemlib/systemlib_lin.ll") 18 | 19 | // link our classes and arc 20 | emt.EmitClassAndArcReferences(module) 21 | 22 | // Version() 23 | //Version := emt.Module.NewFunc("rct_Version", types.I8Ptr) 24 | //body := Version.NewBlock("") 25 | //body.NewRet(emt.CopyStringNoFree(body, emt.GetStringConstant(body, "1.1"))) 26 | 27 | //emt.Functions[tern(emt.UseFingerprints, builtins.Version.Fingerprint(), builtins.Version.Name)] = Function{IRFunction: Version, BoundFunction: binder.BoundFunction{Symbol: builtins.Version}} 28 | 29 | } 30 | 31 | func (emt *Emitter) EmitCLibReferences() { 32 | 33 | malloc := emt.Module.NewFunc("malloc", types.I8Ptr, ir.NewParam("len", types.I32)) 34 | emt.CFuncs["malloc"] = malloc 35 | 36 | free := emt.Module.NewFunc("free", types.Void, ir.NewParam("dest", types.I8Ptr)) 37 | emt.CFuncs["free"] = free 38 | 39 | printf := emt.Module.NewFunc("printf", types.I32, ir.NewParam("format", types.I8Ptr)) 40 | printf.Sig.Variadic = true 41 | emt.CFuncs["printf"] = printf 42 | 43 | snprintf := emt.Module.NewFunc("snprintf", types.I32, ir.NewParam("dest", types.I8Ptr), ir.NewParam("len", types.I32), ir.NewParam("format", types.I8Ptr)) 44 | snprintf.Sig.Variadic = true 45 | emt.CFuncs["snprintf"] = snprintf 46 | 47 | atoi := emt.Module.NewFunc("atoi", types.I32, ir.NewParam("str", types.I8Ptr)) 48 | emt.CFuncs["atoi"] = atoi 49 | 50 | atol := emt.Module.NewFunc("atol", types.I64, ir.NewParam("str", types.I8Ptr)) 51 | emt.CFuncs["atol"] = atol 52 | 53 | atof := emt.Module.NewFunc("atof", types.Double, ir.NewParam("str", types.I8Ptr)) 54 | emt.CFuncs["atof"] = atof 55 | 56 | gc_init := emt.Module.NewFunc("GC_init", types.I8Ptr) 57 | emt.CFuncs["gc_init"] = gc_init 58 | 59 | gc_malloc := emt.Module.NewFunc("GC_malloc", types.I8Ptr, ir.NewParam("len", types.I32)) 60 | emt.CFuncs["gc_malloc"] = gc_malloc 61 | 62 | gc_realloc := emt.Module.NewFunc("GC_realloc", types.I8Ptr, ir.NewParam("ptr", types.I8Ptr), ir.NewParam("len", types.I32)) 63 | emt.CFuncs["gc_realloc"] = gc_realloc 64 | } 65 | 66 | func (emt *Emitter) EmitClassAndArcReferences(module *ir.Module) { 67 | // load module 68 | emt.LoadAndReferenceClasses(module) 69 | 70 | // reference exc functions 71 | excFuncs := irtools.FindFunctionsWithPrefix(module, "exc_") 72 | 73 | for _, fnc := range excFuncs { 74 | emt.ExcFuncs[strings.Split(fnc.Name(), "_")[1]] = fnc 75 | emt.ImportFunction(fnc) 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /emitter/comment.go: -------------------------------------------------------------------------------- 1 | package emitter 2 | 3 | // implementation for a comment 4 | // stolen from github 5 | // https://github.com/llir/llvm/issues/99 6 | 7 | import ( 8 | "strings" 9 | 10 | "github.com/llir/llvm/ir" 11 | ) 12 | 13 | func NewComment(s string) *Comment { 14 | return &Comment{ 15 | Text: s, 16 | } 17 | } 18 | 19 | type Comment struct { 20 | Text string 21 | // embed a dummy ir.Instruction to have Comment implement the ir.Instruction 22 | // interface. 23 | ir.Instruction 24 | } 25 | 26 | func (c *Comment) LLString() string { 27 | return "; " + strings.Replace(c.Text, "\n", "; ", -1) 28 | } 29 | -------------------------------------------------------------------------------- /evaluator/README.md: -------------------------------------------------------------------------------- 1 | # ReCT Evaluator 2 | lets get this road on the show 3 | uh wait no uh hm 4 | hm -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/ReCT-Lang/ReCT-Go-Compiler 2 | 3 | go 1.16 4 | 5 | require ( 6 | github.com/dlclark/regexp2 v1.4.0 7 | github.com/kr/pretty v0.3.0 // indirect 8 | github.com/llir/llvm v0.3.6 9 | github.com/mewmew/float v0.0.0-20211212214546-4fe539893335 // indirect 10 | github.com/rogpeppe/go-internal v1.9.0 // indirect 11 | golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838 12 | golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64 // indirect 13 | golang.org/x/tools v0.1.12 // indirect 14 | golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f // indirect 15 | ) 16 | -------------------------------------------------------------------------------- /irtools/module-reader.go: -------------------------------------------------------------------------------- 1 | package irtools 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 6 | "os" 7 | "strings" 8 | 9 | "github.com/dlclark/regexp2" 10 | "github.com/llir/llvm/asm" 11 | "github.com/llir/llvm/ir" 12 | "github.com/llir/llvm/ir/constant" 13 | ) 14 | 15 | func ReadModule(path string) *ir.Module { 16 | // read out contents of the the file 17 | moduleBytes, _ := os.ReadFile(path) 18 | module := string(moduleBytes) 19 | 20 | // do a regex replace to replace all function content with 'ret void' 21 | re := regexp2.MustCompile(`{\n.*?^}\n`, regexp2.Singleline|regexp2.Multiline) 22 | module, _ = re.Replace(module, " {\n ret void\n}\n", 0, -1) 23 | 24 | // do a regex replace to remove invalid function declarations 25 | re2 := regexp2.MustCompile(`(?<=declare.*?)align [0-9]*`, regexp2.Multiline) 26 | module, _ = re2.Replace(module, " ", 0, -1) 27 | 28 | // do a regex replace to remove invalid function declarations 29 | re3 := regexp2.MustCompile(`(?<=define.*?)align [0-9]*`, regexp2.Multiline) 30 | module, _ = re3.Replace(module, " ", 0, -1) 31 | 32 | os.WriteFile("./mod.ll", []byte(module), os.ModePerm) 33 | 34 | // do a regex replace to remove new fangled sret 35 | //re3 := regexp2.MustCompile(`sret\(.*?\)`, regexp2.Multiline) 36 | //module, _ = re3.Replace(module, " ", 0, -1) 37 | 38 | // parse the module using llir/llvm 39 | irModule, err := asm.ParseString(path, module) 40 | if err != nil { 41 | print.PrintC(print.Red, "Couldnt load module '"+path+"'") 42 | fmt.Println(module) 43 | panic(err) 44 | } 45 | 46 | return irModule 47 | } 48 | 49 | func FindFunctionsWithPrefix(module *ir.Module, prefix string) []*ir.Func { 50 | funcs := make([]*ir.Func, 0) 51 | 52 | for _, fnc := range module.Funcs { 53 | if strings.HasPrefix(fnc.Name(), prefix) { 54 | funcs = append(funcs, fnc) 55 | } 56 | } 57 | 58 | return funcs 59 | } 60 | 61 | func FindFunction(module *ir.Module, name string) *ir.Func { 62 | for _, fnc := range module.Funcs { 63 | if fnc.Name() == name { 64 | return fnc 65 | } 66 | } 67 | 68 | print.PrintC(print.Red, "Couldnt find function '"+name+"'") 69 | return nil 70 | } 71 | 72 | func TryFindFunction(module *ir.Module, name string) *ir.Func { 73 | for _, fnc := range module.Funcs { 74 | if fnc.Name() == name { 75 | return fnc 76 | } 77 | } 78 | 79 | return nil 80 | } 81 | 82 | func FindGlobal(module *ir.Module, name string) *ir.Global { 83 | for _, glb := range module.Globals { 84 | if glb.Name() == name { 85 | return glb 86 | } 87 | } 88 | 89 | print.PrintC(print.Red, "Couldnt find global '"+name+"'") 90 | return nil 91 | } 92 | 93 | func FindGlobalSuffix(module *ir.Module, name string) *ir.Global { 94 | for _, glb := range module.Globals { 95 | if strings.HasSuffix(glb.Name(), name) { 96 | return glb 97 | } 98 | } 99 | 100 | print.PrintC(print.Red, "Couldnt find global '"+name+"'") 101 | return nil 102 | } 103 | 104 | func TryFindGlobal(module *ir.Module, name string) *ir.Global { 105 | for _, glb := range module.Globals { 106 | if glb.Name() == name { 107 | return glb 108 | } 109 | } 110 | 111 | return nil 112 | } 113 | 114 | func ReadConstStringArray(module *ir.Module, glb *ir.Global) ([]string, bool) { 115 | arr, ok := glb.Init.(*constant.Array) 116 | if !ok { 117 | return make([]string, 0), false 118 | } 119 | 120 | names := make([]string, 0) 121 | 122 | for _, elem := range arr.Elems { 123 | gep, ok := elem.(*constant.ExprGetElementPtr) 124 | if !ok { 125 | return make([]string, 0), false 126 | } 127 | 128 | cFld := TryFindGlobal(module, strings.TrimPrefix(gep.Src.Ident(), "@")) 129 | if cFld == nil { 130 | return make([]string, 0), false 131 | } 132 | 133 | chr, ok := cFld.Init.(*constant.CharArray) 134 | if !ok { 135 | return make([]string, 0), false 136 | } 137 | 138 | names = append(names, string(chr.X)) 139 | } 140 | 141 | return names, true 142 | } 143 | -------------------------------------------------------------------------------- /langserverinterface/interface.go: -------------------------------------------------------------------------------- 1 | package langserverinterface 2 | 3 | import ( 4 | "github.com/ReCT-Lang/ReCT-Go-Compiler/lexer" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/symbols" 6 | ) 7 | 8 | // TokenMapping is a Map of meanings 9 | var TokenMapping map[lexer.Token]TokenMeaning 10 | 11 | // TokenMeaning (base class) holds data on what a token actually is 12 | type TokenMeaning interface { 13 | Type() TokenMeaningType 14 | } 15 | 16 | // VariableTokenMeaning holds data about variable tokens 17 | type VariableTokenMeaning struct { 18 | TokenMeaning 19 | 20 | Variable symbols.VariableSymbol // wat dis variabl? 21 | } 22 | 23 | func (m VariableTokenMeaning) Type() TokenMeaningType { 24 | if m.Variable.SymbolType() == symbols.LocalVariable { 25 | return LocalVariableMeaning 26 | } else if m.Variable.SymbolType() == symbols.GlobalVariable { 27 | return GlobalVariableMeaning 28 | } else if m.Variable.SymbolType() == symbols.Parameter { 29 | return ParameterMeaning 30 | } 31 | 32 | return "" 33 | } 34 | 35 | // FunctionTokenMeaning holds data about function ID tokens 36 | type FunctionTokenMeaning struct { 37 | TokenMeaning 38 | 39 | Function symbols.FunctionSymbol // wat dis functn? 40 | } 41 | 42 | func (m FunctionTokenMeaning) Type() TokenMeaningType { 43 | return FunctionMeaning 44 | } 45 | 46 | // FunctionTokenMeaning holds data about function ID tokens 47 | type TypeFunctionTokenMeaning struct { 48 | TokenMeaning 49 | 50 | TypeFunction symbols.TypeFunctionSymbol // wat dis functn? 51 | } 52 | 53 | func (m TypeFunctionTokenMeaning) Type() TokenMeaningType { 54 | return TypeFunctionMeaning 55 | } 56 | 57 | // ClassTokenMeaning holds data about class ID tokens 58 | type ClassTokenMeaning struct { 59 | TokenMeaning 60 | 61 | Class symbols.ClassSymbol // wat dis class? 62 | } 63 | 64 | func (m ClassTokenMeaning) Type() TokenMeaningType { 65 | return ClassMeaning 66 | } 67 | 68 | // StructTokenMeaning holds data about struct ID tokens 69 | type StructTokenMeaning struct { 70 | TokenMeaning 71 | 72 | Struct symbols.StructSymbol // wat dis stct? 73 | } 74 | 75 | func (m StructTokenMeaning) Type() TokenMeaningType { 76 | return StructMeaning 77 | } 78 | 79 | // EnumTokenMeaning holds data about enum ID tokens 80 | type EnumTokenMeaning struct { 81 | TokenMeaning 82 | 83 | Enum symbols.EnumSymbol // wat dis enm? 84 | } 85 | 86 | func (m EnumTokenMeaning) Type() TokenMeaningType { 87 | return EnumMeaning 88 | } 89 | 90 | // EnumFieldTokenMeaning holds data about enum ID tokens 91 | type EnumFieldTokenMeaning struct { 92 | TokenMeaning 93 | 94 | Value int 95 | } 96 | 97 | func (m EnumFieldTokenMeaning) Type() TokenMeaningType { 98 | return EnumFieldMeaning 99 | } 100 | 101 | // PackageTokenMeaning holds data about package ID tokens 102 | type PackageTokenMeaning struct { 103 | TokenMeaning 104 | 105 | Package symbols.PackageSymbol // wat dis enm? 106 | } 107 | 108 | func (m PackageTokenMeaning) Type() TokenMeaningType { 109 | return PackageMeaning 110 | } 111 | 112 | // TypeTokenMeaning holds data about type ID tokens 113 | type TypeTokenMeaning struct { 114 | TokenMeaning 115 | 116 | TypeSym symbols.TypeSymbol // wat dis enm? 117 | } 118 | 119 | func (m TypeTokenMeaning) Type() TokenMeaningType { 120 | return TypeMeaning 121 | } 122 | -------------------------------------------------------------------------------- /langserverinterface/meanings.go: -------------------------------------------------------------------------------- 1 | package langserverinterface 2 | 3 | type TokenMeaningType string 4 | 5 | const ( 6 | LocalVariableMeaning TokenMeaningType = "LocalVariable" 7 | GlobalVariableMeaning TokenMeaningType = "GlobalVariable" 8 | ParameterMeaning TokenMeaningType = "Parameter" 9 | FunctionMeaning TokenMeaningType = "Function" 10 | TypeFunctionMeaning TokenMeaningType = "TypeFunction" 11 | ClassMeaning TokenMeaningType = "Class" 12 | StructMeaning TokenMeaningType = "Struct" 13 | EnumMeaning TokenMeaningType = "Enum" 14 | EnumFieldMeaning TokenMeaningType = "EnumField" 15 | PackageMeaning TokenMeaningType = "Package" 16 | TypeMeaning TokenMeaningType = "Type" 17 | ) 18 | -------------------------------------------------------------------------------- /link_lin.sh: -------------------------------------------------------------------------------- 1 | opt ./out.ll > ./out.bc 2 | llvm-link ./out.bc ./systemlib/systemlib_lin.bc ./packages/sys.bc > ./program.bc 3 | clang -lm -pthread -rdynamic ./program.bc -o ./program -------------------------------------------------------------------------------- /lowerer/README.md: -------------------------------------------------------------------------------- 1 | # ReCT Lowerer 2 | This gamer is responsible for converting complex structures like While, For, From-To loops and if statements into a series of simple label and goto statements. 3 | This is just to make life easier when writing the emitter or interpreter! -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | /* ReCT-Go-Compiler 4 | * Heyyy new cli has been added to main! There are some new flags and stuff you can add (checkout cli.go for docs)... 5 | * Anyway, I suppose you're wondering what to do when compiling a project for development/testing purposes? 6 | * I would recommend running: go build -v -a -o "rgoc" . && ./rgoc -t 7 | * The command above will build the project, create an executable called "rgoc" and run the executable by testing all the test files in /tests/ 8 | * furthermore, you can run: ./rgoc path/to/file.rct, to interpret the file. 9 | */ 10 | 11 | // main it looks super empty because all the handling has moved to cli lol 12 | func main() { 13 | // all these functions can be found in cli.go 14 | 15 | // Init defines all the flags and initializes them 16 | Init() 17 | // ProcessFlags does as it says, takes the flags from Init and uses them to run parts of the compiler 18 | ProcessFlags() 19 | } 20 | -------------------------------------------------------------------------------- /nodes/README.md: -------------------------------------------------------------------------------- 1 | # ReCT Nodes 2 | These nodes are the building blocks of our syntax tree, this is just a place to have them all organized. 3 | -------------------------------------------------------------------------------- /nodes/boundnodes/README.md: -------------------------------------------------------------------------------- 1 | # ReCT Bound Nodes 2 | Here we go again! A folder filled with mysterious node files! 3 | These here are the "bound" version of syntax nodes that have been fed through the Binder. 4 | The main difference is that wonky syntax node things like tokens have been replaced by variable, function, and type symbol references. -------------------------------------------------------------------------------- /nodes/boundnodes/boundUnaryOperator.go: -------------------------------------------------------------------------------- 1 | package boundnodes 2 | 3 | import ( 4 | "github.com/ReCT-Lang/ReCT-Go-Compiler/builtins" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/lexer" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/symbols" 7 | ) 8 | 9 | type BoundUnaryOperatorType string 10 | 11 | const ( 12 | Identity BoundUnaryOperatorType = "Identity" 13 | Negation BoundUnaryOperatorType = "Negation" 14 | LogicalNegation BoundUnaryOperatorType = "LogicalNegation" 15 | ) 16 | 17 | type BoundUnaryOperator struct { 18 | Exists bool 19 | 20 | TokenKind lexer.TokenKind 21 | OperatorKind BoundUnaryOperatorType 22 | OperandType symbols.TypeSymbol 23 | ResultType symbols.TypeSymbol 24 | } 25 | 26 | // constructor 27 | func CreateBoundUnaryOperator(tok lexer.TokenKind, kind BoundUnaryOperatorType, operand symbols.TypeSymbol, result symbols.TypeSymbol) BoundUnaryOperator { 28 | return BoundUnaryOperator{ 29 | Exists: true, 30 | TokenKind: tok, 31 | OperatorKind: kind, 32 | OperandType: operand, 33 | ResultType: result, 34 | } 35 | } 36 | 37 | // allowed operations 38 | var UnaryOperators []BoundUnaryOperator = []BoundUnaryOperator{ 39 | // int operations 40 | /* + */ CreateBoundUnaryOperator(lexer.PlusToken, Identity, builtins.Int, builtins.Int), 41 | /* - */ CreateBoundUnaryOperator(lexer.MinusToken, Negation, builtins.Int, builtins.Int), 42 | 43 | // byte operations 44 | /* + */ CreateBoundUnaryOperator(lexer.PlusToken, Identity, builtins.Byte, builtins.Byte), 45 | /* - */ CreateBoundUnaryOperator(lexer.MinusToken, Negation, builtins.Byte, builtins.Byte), 46 | 47 | // long operations 48 | /* + */ CreateBoundUnaryOperator(lexer.PlusToken, Identity, builtins.Long, builtins.Long), 49 | /* - */ CreateBoundUnaryOperator(lexer.MinusToken, Negation, builtins.Long, builtins.Long), 50 | 51 | // float operations 52 | /* + */ CreateBoundUnaryOperator(lexer.PlusToken, Identity, builtins.Float, builtins.Float), 53 | /* - */ CreateBoundUnaryOperator(lexer.MinusToken, Negation, builtins.Float, builtins.Float), 54 | 55 | // uint operations 56 | /* + */ CreateBoundUnaryOperator(lexer.PlusToken, Identity, builtins.UInt, builtins.UInt), 57 | /* - */ CreateBoundUnaryOperator(lexer.MinusToken, Negation, builtins.UInt, builtins.UInt), 58 | 59 | // ulong operations 60 | /* + */ CreateBoundUnaryOperator(lexer.PlusToken, Identity, builtins.ULong, builtins.ULong), 61 | /* - */ CreateBoundUnaryOperator(lexer.MinusToken, Negation, builtins.ULong, builtins.ULong), 62 | 63 | // double operations 64 | /* + */ CreateBoundUnaryOperator(lexer.PlusToken, Identity, builtins.Double, builtins.Double), 65 | /* - */ CreateBoundUnaryOperator(lexer.MinusToken, Negation, builtins.Double, builtins.Double), 66 | 67 | // bool operations 68 | /* ! */ CreateBoundUnaryOperator(lexer.NotToken, LogicalNegation, builtins.Bool, builtins.Bool), 69 | } 70 | 71 | func BindUnaryOperator(tokenKind lexer.TokenKind, operandType symbols.TypeSymbol) BoundUnaryOperator { 72 | for _, op := range UnaryOperators { 73 | if op.TokenKind == tokenKind && 74 | op.OperandType.Fingerprint() == operandType.Fingerprint() { 75 | return op 76 | } 77 | } 78 | 79 | return BoundUnaryOperator{} 80 | } 81 | -------------------------------------------------------------------------------- /nodes/boundnodes/boundnode.go: -------------------------------------------------------------------------------- 1 | package boundnodes 2 | 3 | import ( 4 | "github.com/ReCT-Lang/ReCT-Go-Compiler/nodes" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/symbols" 6 | ) 7 | 8 | // incredibly cool interface for creating bound nodes 9 | type BoundNode interface { 10 | NodeType() BoundType 11 | Print(indent string) 12 | Source() nodes.SyntaxNode 13 | } 14 | 15 | type BoundStatementNode interface { 16 | BoundNode 17 | } 18 | 19 | type BoundLoopStatementNode interface { 20 | BoundStatementNode 21 | LoopBreakLabel() BoundLabel 22 | LoopContinueLabel() BoundLabel 23 | } 24 | 25 | type BoundLabel string 26 | 27 | type BoundExpressionNode interface { 28 | BoundNode 29 | Type() symbols.TypeSymbol 30 | IsPersistent() bool 31 | } 32 | 33 | // enum for all our node types 34 | type BoundType string 35 | 36 | const ( 37 | 38 | // Statements 39 | BoundBlockStatement BoundType = "BoundBlockStatement" 40 | BoundVariableDeclaration BoundType = "BoundVariableDeclaration" 41 | BoundIfStatement BoundType = "BoundIfStatement" 42 | BoundWhileStatement BoundType = "BoundWhileStatement" 43 | BoundForStatement BoundType = "BoundForStatement" 44 | BoundFromToStatement BoundType = "BoundFromToStatement" 45 | BoundLabelStatement BoundType = "BoundLabelStatement" 46 | BoundGotoStatement BoundType = "BoundGotoStatement" 47 | BoundConditionalGotoStatement BoundType = "BoundConditionalGotoStatement" 48 | BoundReturnStatement BoundType = "BoundReturnStatement" 49 | BoundExpressionStatement BoundType = "BoundExpressionStatement" 50 | 51 | // Expressions 52 | BoundErrorExpression BoundType = "BoundErrorExpression" 53 | BoundLiteralExpression BoundType = "BoundLiteralExpression" 54 | BoundVariableExpression BoundType = "BoundVariableExpression" 55 | BoundAssignmentExpression BoundType = "BoundAssignmentExpression" 56 | BoundUnaryExpression BoundType = "BoundUnaryExpression" 57 | BoundBinaryExpression BoundType = "BoundBinaryExpression" 58 | BoundCallExpression BoundType = "BoundCallExpression" 59 | BoundPackageCallExpression BoundType = "BoundPackageCallExpression" 60 | BoundConversionExpression BoundType = "BoundConversionExpression" 61 | BoundTypeCallExpression BoundType = "BoundTypeCallExpression" 62 | BoundClassCallExpression BoundType = "BoundClassCallExpression" 63 | BoundClassFieldAccessExpression BoundType = "BoundClassFieldAccessExpression" 64 | BoundClassFieldAssignmentExpression BoundType = "BoundClassFieldAssignmentExpression" 65 | BoundArrayAccessExpression BoundType = "BoundArrayAccessExpression" 66 | BoundArrayAssignmentExpression BoundType = "BoundArrayAssignmentExpression" 67 | BoundMakeExpression BoundType = "BoundMakeExpression" 68 | BoundMakeArrayExpression BoundType = "BoundMakeArrayExpression" 69 | BoundFunctionExpression BoundType = "BoundFunctionExpression" 70 | BoundTernaryExpression BoundType = "BoundTernaryExpression" 71 | BoundReferenceExpression BoundType = "BoundReferenceExpression" 72 | BoundDereferenceExpression BoundType = "BoundDereferenceExpression" 73 | BoundMakeStructExpression BoundType = "BoundMakeStructExpression" 74 | BoundLambdaExpression BoundType = "BoundLambdaExpression" 75 | BoundThisExpression BoundType = "BoundThisExpression" 76 | BoundInternalValueExpression BoundType = "BoundInternalValueExpression" 77 | BoundEnumExpression BoundType = "BoundEnumExpression" 78 | ) 79 | -------------------------------------------------------------------------------- /nodes/boundnodes/expr-boundArrayAccessExpression.go: -------------------------------------------------------------------------------- 1 | package boundnodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/nodes" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | "github.com/ReCT-Lang/ReCT-Go-Compiler/symbols" 8 | ) 9 | 10 | type BoundArrayAccessExpressionNode struct { 11 | BoundExpressionNode 12 | 13 | Base BoundExpressionNode 14 | Index BoundExpressionNode 15 | IsPointer bool 16 | UnboundSource nodes.SyntaxNode 17 | } 18 | 19 | func (BoundArrayAccessExpressionNode) NodeType() BoundType { return BoundArrayAccessExpression } 20 | 21 | func (node BoundArrayAccessExpressionNode) Source() nodes.SyntaxNode { 22 | return node.UnboundSource 23 | } 24 | 25 | func (node BoundArrayAccessExpressionNode) Print(indent string) { 26 | print.PrintC(print.Yellow, indent+"└ BoundArrayAccessExpression") 27 | fmt.Println(indent + " └ Base: ") 28 | node.Base.Print(indent + " ") 29 | fmt.Println(indent + " └ Index: ") 30 | node.Index.Print(indent + " ") 31 | } 32 | 33 | func (BoundArrayAccessExpressionNode) IsPersistent() bool { return true } 34 | 35 | // implement the expression node interface 36 | func (node BoundArrayAccessExpressionNode) Type() symbols.TypeSymbol { 37 | return node.Base.Type().SubTypes[0] 38 | } 39 | 40 | func CreateBoundArrayAccessExpressionNode(base BoundExpressionNode, index BoundExpressionNode, isPointer bool, src nodes.SyntaxNode) BoundArrayAccessExpressionNode { 41 | return BoundArrayAccessExpressionNode{ 42 | Base: base, 43 | Index: index, 44 | IsPointer: isPointer, 45 | UnboundSource: src, 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /nodes/boundnodes/expr-boundArrayAssignmentExpression.go: -------------------------------------------------------------------------------- 1 | package boundnodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/nodes" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | "github.com/ReCT-Lang/ReCT-Go-Compiler/symbols" 8 | ) 9 | 10 | type BoundArrayAssignmentExpressionNode struct { 11 | BoundExpressionNode 12 | 13 | Base BoundExpressionNode 14 | Index BoundExpressionNode 15 | Value BoundExpressionNode 16 | IsPointer bool 17 | 18 | UnboundSource nodes.SyntaxNode 19 | } 20 | 21 | func (BoundArrayAssignmentExpressionNode) NodeType() BoundType { return BoundArrayAssignmentExpression } 22 | 23 | func (node BoundArrayAssignmentExpressionNode) Source() nodes.SyntaxNode { 24 | return node.UnboundSource 25 | } 26 | 27 | func (node BoundArrayAssignmentExpressionNode) Print(indent string) { 28 | print.PrintC(print.Yellow, indent+"└ BoundArrayAssignmentExpression") 29 | fmt.Println(indent + " └ Base: ") 30 | node.Base.Print(indent + " ") 31 | fmt.Println(indent + " └ Index: ") 32 | node.Index.Print(indent + " ") 33 | fmt.Println(indent + " └ Value: ") 34 | node.Value.Print(indent + " ") 35 | } 36 | 37 | func (BoundArrayAssignmentExpressionNode) IsPersistent() bool { return true } 38 | 39 | // implement the expression node interface 40 | func (node BoundArrayAssignmentExpressionNode) Type() symbols.TypeSymbol { 41 | return node.Base.Type().SubTypes[0] 42 | } 43 | 44 | func CreateBoundArrayAssignmentExpressionNode(base BoundExpressionNode, index BoundExpressionNode, value BoundExpressionNode, isPointer bool, src nodes.SyntaxNode) BoundArrayAssignmentExpressionNode { 45 | return BoundArrayAssignmentExpressionNode{ 46 | Base: base, 47 | Index: index, 48 | Value: value, 49 | IsPointer: isPointer, 50 | UnboundSource: src, 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /nodes/boundnodes/expr-boundAssignmentExpression.go: -------------------------------------------------------------------------------- 1 | package boundnodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/nodes" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | "github.com/ReCT-Lang/ReCT-Go-Compiler/symbols" 8 | ) 9 | 10 | type BoundAssignmentExpressionNode struct { 11 | BoundExpressionNode 12 | 13 | InMain bool 14 | 15 | Variable symbols.VariableSymbol 16 | Expression BoundExpressionNode 17 | UnboundSource nodes.SyntaxNode 18 | } 19 | 20 | func (BoundAssignmentExpressionNode) NodeType() BoundType { return BoundAssignmentExpression } 21 | 22 | func (node BoundAssignmentExpressionNode) Source() nodes.SyntaxNode { 23 | return node.UnboundSource 24 | } 25 | 26 | func (node BoundAssignmentExpressionNode) Print(indent string) { 27 | print.PrintC(print.Yellow, indent+"└ BoundAssignmentExpressionNode") 28 | fmt.Println(indent + " └ Variable: ") 29 | node.Variable.Print(indent + " ") 30 | fmt.Println(indent + " └ Expression: ") 31 | node.Expression.Print(indent + " ") 32 | } 33 | 34 | func (BoundAssignmentExpressionNode) IsPersistent() bool { return false } 35 | 36 | // implement the expression node interface 37 | func (node BoundAssignmentExpressionNode) Type() symbols.TypeSymbol { return node.Expression.Type() } 38 | 39 | func CreateBoundAssignmentExpressionNode(variable symbols.VariableSymbol, expression BoundExpressionNode, inMain bool, src nodes.SyntaxNode) BoundAssignmentExpressionNode { 40 | return BoundAssignmentExpressionNode{ 41 | Variable: variable, 42 | Expression: expression, 43 | InMain: inMain, 44 | UnboundSource: src, 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /nodes/boundnodes/expr-boundBinaryExpression.go: -------------------------------------------------------------------------------- 1 | package boundnodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/nodes" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | "github.com/ReCT-Lang/ReCT-Go-Compiler/symbols" 8 | ) 9 | 10 | type BoundBinaryExpressionNode struct { 11 | BoundExpressionNode 12 | 13 | Left BoundExpressionNode 14 | Op BoundBinaryOperator 15 | Right BoundExpressionNode 16 | UnboundSource nodes.SyntaxNode 17 | } 18 | 19 | func (BoundBinaryExpressionNode) NodeType() BoundType { return BoundBinaryExpression } 20 | 21 | func (node BoundBinaryExpressionNode) Source() nodes.SyntaxNode { 22 | return node.UnboundSource 23 | } 24 | 25 | func (node BoundBinaryExpressionNode) Print(indent string) { 26 | print.PrintC(print.Yellow, indent+"└ BoundBinaryExpressionNode") 27 | fmt.Println(indent + " └ Left: ") 28 | node.Left.Print(indent + " ") 29 | fmt.Printf("%s └ Operator: %s\n", indent, node.Op.OperatorKind) 30 | fmt.Println(indent + " └ Right: ") 31 | node.Right.Print(indent + " ") 32 | } 33 | 34 | func (BoundBinaryExpressionNode) IsPersistent() bool { return false } 35 | 36 | // implement the expression node interface 37 | func (node BoundBinaryExpressionNode) Type() symbols.TypeSymbol { return node.Op.ResultType } 38 | 39 | func CreateBoundBinaryExpressionNode(left BoundExpressionNode, op BoundBinaryOperator, right BoundExpressionNode, src nodes.SyntaxNode) BoundBinaryExpressionNode { 40 | return BoundBinaryExpressionNode{ 41 | Left: left, 42 | Op: op, 43 | Right: right, 44 | UnboundSource: src, 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /nodes/boundnodes/expr-boundCallExpression.go: -------------------------------------------------------------------------------- 1 | package boundnodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/nodes" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | "github.com/ReCT-Lang/ReCT-Go-Compiler/symbols" 8 | ) 9 | 10 | type BoundCallExpressionNode struct { 11 | BoundExpressionNode 12 | 13 | InMain bool 14 | 15 | Function symbols.FunctionSymbol 16 | Arguments []BoundExpressionNode 17 | UnboundSource nodes.SyntaxNode 18 | } 19 | 20 | func (BoundCallExpressionNode) NodeType() BoundType { return BoundCallExpression } 21 | 22 | func (node BoundCallExpressionNode) Source() nodes.SyntaxNode { 23 | return node.UnboundSource 24 | } 25 | 26 | func (node BoundCallExpressionNode) Print(indent string) { 27 | print.PrintC(print.Yellow, indent+"└ BoundCallExpressionNode") 28 | node.Function.Print(indent) 29 | fmt.Println(indent + " └ Arguments: ") 30 | for _, arg := range node.Arguments { 31 | arg.Print(indent + " ") 32 | } 33 | } 34 | 35 | func (BoundCallExpressionNode) IsPersistent() bool { return false } 36 | 37 | // implement the expression node interface 38 | func (node BoundCallExpressionNode) Type() symbols.TypeSymbol { return node.Function.Type } 39 | 40 | func CreateBoundCallExpressionNode(function symbols.FunctionSymbol, args []BoundExpressionNode, inMain bool, src nodes.SyntaxNode) BoundCallExpressionNode { 41 | return BoundCallExpressionNode{ 42 | Function: function, 43 | Arguments: args, 44 | InMain: inMain, 45 | UnboundSource: src, 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /nodes/boundnodes/expr-boundClassCallExpression.go: -------------------------------------------------------------------------------- 1 | package boundnodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/nodes" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | "github.com/ReCT-Lang/ReCT-Go-Compiler/symbols" 8 | ) 9 | 10 | type BoundClassCallExpressionNode struct { 11 | BoundExpressionNode 12 | 13 | Base BoundExpressionNode 14 | Function symbols.FunctionSymbol 15 | Arguments []BoundExpressionNode 16 | 17 | UnboundSource nodes.SyntaxNode 18 | } 19 | 20 | // implement node type from interface 21 | func (BoundClassCallExpressionNode) NodeType() BoundType { return BoundClassCallExpression } 22 | 23 | // implement the expression node interface 24 | func (node BoundClassCallExpressionNode) Type() symbols.TypeSymbol { return node.Function.Type } 25 | 26 | func (node BoundClassCallExpressionNode) Source() nodes.SyntaxNode { 27 | return node.UnboundSource 28 | } 29 | 30 | // node print function 31 | func (node BoundClassCallExpressionNode) Print(indent string) { 32 | print.PrintC(print.Yellow, indent+"└ BoundClassCallExpressionNode") 33 | fmt.Println(indent + " └ Base: ") 34 | node.Base.Print(indent + " ") 35 | fmt.Println(indent + " └ Function: ") 36 | node.Function.Print(indent + " ") 37 | fmt.Println(indent + " └ Arguments: ") 38 | for _, arg := range node.Arguments { 39 | arg.Print(indent + " ") 40 | } 41 | } 42 | 43 | func (BoundClassCallExpressionNode) IsPersistent() bool { return false } 44 | 45 | // "constructor" / ooga booga OOP cave man brain 46 | func CreateBoundClassCallExpressionNode( 47 | base BoundExpressionNode, 48 | callId symbols.FunctionSymbol, 49 | args []BoundExpressionNode, 50 | src nodes.SyntaxNode, 51 | ) BoundClassCallExpressionNode { 52 | return BoundClassCallExpressionNode{ 53 | Base: base, 54 | Function: callId, 55 | Arguments: args, 56 | UnboundSource: src, 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /nodes/boundnodes/expr-boundClassFieldAccessExpression.go: -------------------------------------------------------------------------------- 1 | package boundnodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/nodes" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | "github.com/ReCT-Lang/ReCT-Go-Compiler/symbols" 8 | ) 9 | 10 | type BoundClassFieldAccessExpressionNode struct { 11 | BoundExpressionNode 12 | 13 | Base BoundExpressionNode 14 | Field symbols.VariableSymbol 15 | UnboundSource nodes.SyntaxNode 16 | } 17 | 18 | // implement node type from interface 19 | func (BoundClassFieldAccessExpressionNode) NodeType() BoundType { 20 | return BoundClassFieldAccessExpression 21 | } 22 | 23 | // implement the expression node interface 24 | func (node BoundClassFieldAccessExpressionNode) Type() symbols.TypeSymbol { 25 | return node.Field.VarType() 26 | } 27 | 28 | func (node BoundClassFieldAccessExpressionNode) Source() nodes.SyntaxNode { 29 | return node.UnboundSource 30 | } 31 | 32 | // node print function 33 | func (node BoundClassFieldAccessExpressionNode) Print(indent string) { 34 | print.PrintC(print.Yellow, indent+"└ BoundClassFieldAccessExpressionNode") 35 | fmt.Println(indent + " └ Base: ") 36 | node.Base.Print(indent + " ") 37 | fmt.Println(indent + " └ Field: ") 38 | node.Field.Print(indent + " ") 39 | } 40 | 41 | func (BoundClassFieldAccessExpressionNode) IsPersistent() bool { return true } 42 | 43 | // "constructor" / ooga booga OOP cave man brain 44 | func CreateBoundClassFieldAccessExpressionNode(base BoundExpressionNode, field symbols.VariableSymbol, src nodes.SyntaxNode) BoundClassFieldAccessExpressionNode { 45 | return BoundClassFieldAccessExpressionNode{ 46 | Base: base, 47 | Field: field, 48 | UnboundSource: src, 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /nodes/boundnodes/expr-boundClassFieldAssignmentExpression.go: -------------------------------------------------------------------------------- 1 | package boundnodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/nodes" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | "github.com/ReCT-Lang/ReCT-Go-Compiler/symbols" 8 | ) 9 | 10 | type BoundClassFieldAssignmentExpressionNode struct { 11 | BoundExpressionNode 12 | 13 | Base BoundExpressionNode 14 | Field symbols.VariableSymbol 15 | Value BoundExpressionNode 16 | 17 | UnboundSource nodes.SyntaxNode 18 | } 19 | 20 | // implement node type from interface 21 | func (BoundClassFieldAssignmentExpressionNode) NodeType() BoundType { 22 | return BoundClassFieldAssignmentExpression 23 | } 24 | 25 | // implement the expression node interface 26 | func (node BoundClassFieldAssignmentExpressionNode) Type() symbols.TypeSymbol { 27 | return node.Field.VarType() 28 | } 29 | 30 | func (node BoundClassFieldAssignmentExpressionNode) Source() nodes.SyntaxNode { 31 | return node.UnboundSource 32 | } 33 | 34 | // node print function 35 | func (node BoundClassFieldAssignmentExpressionNode) Print(indent string) { 36 | print.PrintC(print.Yellow, indent+"└ BoundClassFieldAssignmentExpressionNode") 37 | fmt.Println(indent + " └ Base: ") 38 | node.Base.Print(indent + " ") 39 | fmt.Println(indent + " └ Field: ") 40 | node.Field.Print(indent + " ") 41 | fmt.Println(indent + " └ Value: ") 42 | node.Value.Print(indent + " ") 43 | } 44 | 45 | func (BoundClassFieldAssignmentExpressionNode) IsPersistent() bool { return true } 46 | 47 | // "constructor" / ooga booga OOP cave man brain 48 | func CreateBoundClassFieldAssignmentExpressionNode(base BoundExpressionNode, field symbols.VariableSymbol, value BoundExpressionNode, src nodes.SyntaxNode) BoundClassFieldAssignmentExpressionNode { 49 | return BoundClassFieldAssignmentExpressionNode{ 50 | Base: base, 51 | Field: field, 52 | Value: value, 53 | UnboundSource: src, 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /nodes/boundnodes/expr-boundConversionExpression.go: -------------------------------------------------------------------------------- 1 | package boundnodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/nodes" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | "github.com/ReCT-Lang/ReCT-Go-Compiler/symbols" 8 | ) 9 | 10 | type BoundConversionExpressionNode struct { 11 | BoundExpressionNode 12 | 13 | Expression BoundExpressionNode 14 | ToType symbols.TypeSymbol 15 | UnboundSource nodes.SyntaxNode 16 | } 17 | 18 | func (BoundConversionExpressionNode) NodeType() BoundType { return BoundConversionExpression } 19 | 20 | func (node BoundConversionExpressionNode) Print(indent string) { 21 | print.PrintC(print.Yellow, indent+"└ BoundConversionExpressionNode") 22 | fmt.Println(indent + " └ Type: ") 23 | node.ToType.Print(indent + " ") 24 | fmt.Println(indent + " └ Expression: ") 25 | node.Expression.Print(indent + " ") 26 | } 27 | 28 | func (node BoundConversionExpressionNode) Source() nodes.SyntaxNode { 29 | return node.UnboundSource 30 | } 31 | 32 | func (node BoundConversionExpressionNode) IsPersistent() bool { 33 | // object -> object ---> persistent, if the object is 34 | if node.Expression.Type().IsObject && node.ToType.IsObject { 35 | return node.Expression.IsPersistent() 36 | } 37 | 38 | // object -> primitive ---> not persistent, primitives dont need cleanup 39 | if node.Expression.Type().IsObject && !node.ToType.IsObject { 40 | return false 41 | } 42 | 43 | // primitive -> object ---> never persistent, objects are created and need cleanup 44 | // (a converted object can be made persistent by handing it to a variable for management) 45 | if !node.Expression.Type().IsObject && node.ToType.IsObject { 46 | return false 47 | } 48 | 49 | return false 50 | } 51 | 52 | // implement the expression node interface 53 | func (node BoundConversionExpressionNode) Type() symbols.TypeSymbol { return node.ToType } 54 | 55 | func CreateBoundConversionExpressionNode(_type symbols.TypeSymbol, expression BoundExpressionNode, src nodes.SyntaxNode) BoundConversionExpressionNode { 56 | return BoundConversionExpressionNode{ 57 | ToType: _type, 58 | Expression: expression, 59 | UnboundSource: src, 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /nodes/boundnodes/expr-boundDereferenceExpression.go: -------------------------------------------------------------------------------- 1 | package boundnodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/nodes" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | "github.com/ReCT-Lang/ReCT-Go-Compiler/symbols" 8 | ) 9 | 10 | type BoundDereferenceExpressionNode struct { 11 | BoundExpressionNode 12 | 13 | Expression BoundExpressionNode 14 | UnboundSource nodes.SyntaxNode 15 | } 16 | 17 | func (BoundDereferenceExpressionNode) NodeType() BoundType { return BoundDereferenceExpression } 18 | 19 | func (node BoundDereferenceExpressionNode) Source() nodes.SyntaxNode { 20 | return node.UnboundSource 21 | } 22 | 23 | func (node BoundDereferenceExpressionNode) Print(indent string) { 24 | print.PrintC(print.Yellow, indent+"└ BoundReferenceExpressionNode") 25 | fmt.Println(indent + " └ Expression: ") 26 | node.Expression.Print(indent + " ") 27 | } 28 | 29 | func (node BoundDereferenceExpressionNode) IsPersistent() bool { return node.Expression.IsPersistent() } 30 | 31 | // implement the expression node interface 32 | func (node BoundDereferenceExpressionNode) Type() symbols.TypeSymbol { 33 | return node.Expression.Type().SubTypes[0] 34 | } 35 | 36 | func CreateBoundDereferenceExpressionNode(expression BoundExpressionNode, src nodes.SyntaxNode) BoundDereferenceExpressionNode { 37 | return BoundDereferenceExpressionNode{ 38 | Expression: expression, 39 | UnboundSource: src, 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /nodes/boundnodes/expr-boundEnumExpression.go: -------------------------------------------------------------------------------- 1 | package boundnodes 2 | 3 | import ( 4 | "github.com/ReCT-Lang/ReCT-Go-Compiler/nodes" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/symbols" 7 | ) 8 | 9 | // basic global statement member 10 | type BoundEnumExpressionNode struct { 11 | BoundExpressionNode 12 | 13 | Value int 14 | Enum symbols.EnumSymbol 15 | UnboundSource nodes.SyntaxNode 16 | } 17 | 18 | // implement node type from interface 19 | func (BoundEnumExpressionNode) NodeType() BoundType { return BoundEnumExpression } 20 | 21 | // node print function 22 | func (node BoundEnumExpressionNode) Print(indent string) { 23 | print.PrintC(print.Yellow, indent+"└ BoundEnumExpressionNode") 24 | } 25 | 26 | func (node BoundEnumExpressionNode) Source() nodes.SyntaxNode { 27 | return node.UnboundSource 28 | } 29 | 30 | func (BoundEnumExpressionNode) IsPersistent() bool { return false } 31 | 32 | // implement the expression node interface 33 | func (node BoundEnumExpressionNode) Type() symbols.TypeSymbol { return node.Enum.Type } 34 | 35 | // Doubt this is right 36 | func CreateBoundEnumExpressionNode(val int, enm symbols.EnumSymbol, src nodes.SyntaxNode) BoundEnumExpressionNode { 37 | return BoundEnumExpressionNode{ 38 | Value: val, 39 | Enum: enm, 40 | UnboundSource: src, 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /nodes/boundnodes/expr-boundErrorExpression.go: -------------------------------------------------------------------------------- 1 | package boundnodes 2 | 3 | import ( 4 | "github.com/ReCT-Lang/ReCT-Go-Compiler/builtins" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/nodes" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | "github.com/ReCT-Lang/ReCT-Go-Compiler/symbols" 8 | ) 9 | 10 | type BoundErrorExpressionNode struct { 11 | BoundExpressionNode 12 | UnboundSource nodes.SyntaxNode 13 | } 14 | 15 | func (BoundErrorExpressionNode) NodeType() BoundType { return BoundErrorExpression } 16 | 17 | func (node BoundErrorExpressionNode) Print(indent string) { 18 | print.PrintC(print.Yellow, indent+"└ BoundErrorExpressionNode") 19 | } 20 | 21 | func (node BoundErrorExpressionNode) Source() nodes.SyntaxNode { 22 | return node.UnboundSource 23 | } 24 | 25 | func (BoundErrorExpressionNode) IsPersistent() bool { return false } 26 | 27 | // implement the expression node interface 28 | func (node BoundErrorExpressionNode) Type() symbols.TypeSymbol { return builtins.Error } 29 | 30 | func CreateBoundErrorExpressionNode(src nodes.SyntaxNode) BoundErrorExpressionNode { 31 | return BoundErrorExpressionNode{ 32 | UnboundSource: src, 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /nodes/boundnodes/expr-boundFunctionExpression.go: -------------------------------------------------------------------------------- 1 | package boundnodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/nodes" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | "github.com/ReCT-Lang/ReCT-Go-Compiler/symbols" 8 | ) 9 | 10 | type BoundFunctionExpressionNode struct { 11 | BoundExpressionNode 12 | 13 | InClass symbols.ClassSymbol 14 | Function symbols.FunctionSymbol 15 | UnboundSource nodes.SyntaxNode 16 | } 17 | 18 | func (BoundFunctionExpressionNode) NodeType() BoundType { return BoundFunctionExpression } 19 | 20 | func (node BoundFunctionExpressionNode) Print(indent string) { 21 | print.PrintC(print.Yellow, indent+"└ BoundFunctionExpressionNode") 22 | fmt.Println(indent + " └ Function: ") 23 | node.Function.Print(indent + " ") 24 | } 25 | 26 | func (node BoundFunctionExpressionNode) Source() nodes.SyntaxNode { 27 | return node.UnboundSource 28 | } 29 | 30 | func (BoundFunctionExpressionNode) IsPersistent() bool { return false } 31 | 32 | // implement the expression node interface 33 | func (node BoundFunctionExpressionNode) Type() symbols.TypeSymbol { 34 | // create cool typesymbol 35 | subtypes := make([]symbols.TypeSymbol, 0) 36 | 37 | // if this function is inside a class -> add the obj as the first parameter (bc thats how it be) 38 | if node.InClass.Exists { 39 | subtypes = append(subtypes, node.InClass.Type) 40 | } 41 | 42 | // [prm1, prm2, returnType] 43 | for _, parameter := range node.Function.Parameters { 44 | subtypes = append(subtypes, parameter.Type) 45 | } 46 | subtypes = append(subtypes, node.Function.Type) 47 | 48 | return symbols.CreateTypeSymbol("action", subtypes, false, false, false, symbols.PackageSymbol{}, nil) 49 | } 50 | 51 | func CreateBoundFunctionExpressionNode(function symbols.FunctionSymbol, src nodes.SyntaxNode) BoundFunctionExpressionNode { 52 | return BoundFunctionExpressionNode{ 53 | Function: function, 54 | UnboundSource: src, 55 | } 56 | } 57 | 58 | func CreateBoundFunctionInClassExpressionNode(function symbols.FunctionSymbol, class symbols.ClassSymbol, src nodes.SyntaxNode) BoundFunctionExpressionNode { 59 | return BoundFunctionExpressionNode{ 60 | Function: function, 61 | InClass: class, 62 | UnboundSource: src, 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /nodes/boundnodes/expr-boundInternalValueExpression.go: -------------------------------------------------------------------------------- 1 | package boundnodes 2 | 3 | import ( 4 | "github.com/ReCT-Lang/ReCT-Go-Compiler/nodes" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/symbols" 7 | "github.com/llir/llvm/ir/value" 8 | ) 9 | 10 | // basic global statement member 11 | type BoundInternalValueExpressionNode struct { 12 | BoundExpressionNode 13 | 14 | Value value.Value 15 | ValueType symbols.TypeSymbol 16 | } 17 | 18 | // implement node type from interface 19 | func (BoundInternalValueExpressionNode) NodeType() BoundType { return BoundInternalValueExpression } 20 | 21 | // node print function 22 | func (node BoundInternalValueExpressionNode) Print(indent string) { 23 | print.PrintC(print.Yellow, indent+"└ BoundInternalValueExpressionNode") 24 | } 25 | 26 | func (node BoundInternalValueExpressionNode) Source() nodes.SyntaxNode { 27 | return nil 28 | } 29 | 30 | func (BoundInternalValueExpressionNode) IsPersistent() bool { return false } 31 | 32 | // implement the expression node interface 33 | func (node BoundInternalValueExpressionNode) Type() symbols.TypeSymbol { return node.ValueType } 34 | 35 | // Doubt this is right 36 | func CreateBoundInternalValueExpressionNode(val value.Value, typ symbols.TypeSymbol) BoundInternalValueExpressionNode { 37 | return BoundInternalValueExpressionNode{ 38 | Value: val, 39 | ValueType: typ, 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /nodes/boundnodes/expr-boundLambdaExpression.go: -------------------------------------------------------------------------------- 1 | package boundnodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/nodes" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | "github.com/ReCT-Lang/ReCT-Go-Compiler/symbols" 8 | ) 9 | 10 | type BoundLambdaExpressionNode struct { 11 | BoundExpressionNode 12 | 13 | Function symbols.FunctionSymbol 14 | Body BoundBlockStatementNode 15 | UnboundSource nodes.SyntaxNode 16 | } 17 | 18 | func (BoundLambdaExpressionNode) NodeType() BoundType { return BoundLambdaExpression } 19 | 20 | func (node BoundLambdaExpressionNode) Print(indent string) { 21 | print.PrintC(print.Yellow, indent+"└ BoundLambdaExpressionNode") 22 | fmt.Println(indent + " └ Symbol: ") 23 | node.Function.Print(indent + " ") 24 | } 25 | 26 | func (node BoundLambdaExpressionNode) Source() nodes.SyntaxNode { 27 | return node.UnboundSource 28 | } 29 | 30 | func (BoundLambdaExpressionNode) IsPersistent() bool { return false } 31 | 32 | // implement the expression node interface 33 | func (node BoundLambdaExpressionNode) Type() symbols.TypeSymbol { 34 | // create cool typesymbol 35 | subtypes := make([]symbols.TypeSymbol, 0) 36 | 37 | // [prm1, prm2, returnType] 38 | for _, parameter := range node.Function.Parameters { 39 | subtypes = append(subtypes, parameter.Type) 40 | } 41 | subtypes = append(subtypes, node.Function.Type) 42 | 43 | return symbols.CreateTypeSymbol("action", subtypes, false, false, false, symbols.PackageSymbol{}, nil) 44 | } 45 | 46 | func CreateBoundLambdaExpressionNode(function symbols.FunctionSymbol, body BoundBlockStatementNode, src nodes.SyntaxNode) BoundLambdaExpressionNode { 47 | return BoundLambdaExpressionNode{ 48 | Function: function, 49 | Body: body, 50 | UnboundSource: src, 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /nodes/boundnodes/expr-boundLiteralExpression.go: -------------------------------------------------------------------------------- 1 | package boundnodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/builtins" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/nodes" 7 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 8 | "github.com/ReCT-Lang/ReCT-Go-Compiler/symbols" 9 | "os" 10 | ) 11 | 12 | // basic global statement member 13 | type BoundLiteralExpressionNode struct { 14 | BoundExpressionNode 15 | 16 | Value interface{} 17 | LiteralType symbols.TypeSymbol 18 | UnboundSource nodes.SyntaxNode 19 | } 20 | 21 | // implement node type from interface 22 | func (BoundLiteralExpressionNode) NodeType() BoundType { return BoundLiteralExpression } 23 | 24 | // node print function 25 | func (node BoundLiteralExpressionNode) Print(indent string) { 26 | print.PrintC(print.Yellow, indent+"└ BoundLiteralExpressionNode") 27 | 28 | if node.LiteralType.Fingerprint() == builtins.String.Fingerprint() { 29 | fmt.Printf("%s └ Value: %s\n", indent, node.Value.(string)) 30 | 31 | } else if node.LiteralType.Fingerprint() == builtins.Int.Fingerprint() { 32 | fmt.Printf("%s └ Value: %d\n", indent, node.Value.(int)) 33 | 34 | } else if node.LiteralType.Fingerprint() == builtins.Bool.Fingerprint() { 35 | fmt.Printf("%s └ Value: %t\n", indent, node.Value.(bool)) 36 | } 37 | fmt.Println(indent + " └ Type: ") 38 | node.LiteralType.Print(indent + " ") 39 | } 40 | 41 | func (node BoundLiteralExpressionNode) Source() nodes.SyntaxNode { 42 | return node.UnboundSource 43 | } 44 | 45 | func (BoundLiteralExpressionNode) IsPersistent() bool { return false } 46 | 47 | // implement the expression node interface 48 | func (node BoundLiteralExpressionNode) Type() symbols.TypeSymbol { return node.LiteralType } 49 | 50 | // Doubt this is right 51 | func CreateBoundLiteralExpressionNode(expr nodes.LiteralExpressionNode, src nodes.SyntaxNode) BoundLiteralExpressionNode { 52 | var _type symbols.TypeSymbol 53 | switch expr.LiteralValue.(type) { 54 | case string: 55 | if expr.IsNative { 56 | _type = symbols.CreateTypeSymbol("pointer", []symbols.TypeSymbol{builtins.Byte}, false, false, false, symbols.PackageSymbol{}, nil) 57 | } else { 58 | _type = builtins.String 59 | } 60 | case bool: 61 | _type = builtins.Bool 62 | case int, int32: 63 | _type = builtins.Int 64 | case float32: 65 | _type = builtins.Float 66 | default: 67 | print.PrintC( 68 | print.Red, 69 | fmt.Sprintf("ERROR: Uknown type symbol \"%s\" debug: (BoundLiteralExpressionNode line 40)", expr.LiteralValue.(string)), 70 | ) 71 | os.Exit(1) // shrug 72 | } 73 | return BoundLiteralExpressionNode{ 74 | Value: expr.LiteralValue, 75 | LiteralType: _type, 76 | UnboundSource: src, 77 | } 78 | } 79 | 80 | func CreateBoundLiteralExpressionNodeFromValue(value interface{}, src nodes.SyntaxNode) BoundLiteralExpressionNode { 81 | var _type symbols.TypeSymbol 82 | switch value.(type) { 83 | case string: 84 | _type = builtins.String 85 | case bool: 86 | _type = builtins.Bool 87 | case int, int32: 88 | _type = builtins.Int 89 | case int64: 90 | _type = builtins.Long 91 | case byte: 92 | _type = builtins.Byte 93 | case float32: 94 | _type = builtins.Float 95 | default: 96 | print.PrintC( 97 | print.Red, 98 | fmt.Sprintf("ERROR: Uknown type symbol \"%s\" debug: (BoundLiteralExpressionNode line 40)", value.(string)), 99 | ) 100 | os.Exit(1) // shrug 101 | } 102 | return BoundLiteralExpressionNode{ 103 | Value: value, 104 | LiteralType: _type, 105 | UnboundSource: src, 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /nodes/boundnodes/expr-boundMakeArrayExpression.go: -------------------------------------------------------------------------------- 1 | package boundnodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/nodes" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | "github.com/ReCT-Lang/ReCT-Go-Compiler/symbols" 8 | ) 9 | 10 | type BoundMakeArrayExpressionNode struct { 11 | BoundExpressionNode 12 | 13 | IsLiteral bool 14 | BaseType symbols.TypeSymbol 15 | Length BoundExpressionNode 16 | Literals []BoundExpressionNode 17 | 18 | UnboundSource nodes.SyntaxNode 19 | } 20 | 21 | func (BoundMakeArrayExpressionNode) NodeType() BoundType { return BoundMakeArrayExpression } 22 | 23 | func (node BoundMakeArrayExpressionNode) Print(indent string) { 24 | print.PrintC(print.Yellow, indent+"└ BoundMakeArrayExpressionNode") 25 | fmt.Println(indent + " └ Type: ") 26 | node.BaseType.Print(indent + " ") 27 | //fmt.Println(indent + " └ Length: ") 28 | //node.Length.Print(indent + " ") 29 | } 30 | 31 | func (node BoundMakeArrayExpressionNode) Source() nodes.SyntaxNode { 32 | return node.UnboundSource 33 | } 34 | 35 | func (BoundMakeArrayExpressionNode) IsPersistent() bool { return false } 36 | 37 | // implement the expression node interface 38 | func (node BoundMakeArrayExpressionNode) Type() symbols.TypeSymbol { 39 | return symbols.CreateTypeSymbol("array", []symbols.TypeSymbol{node.BaseType}, true, false, false, symbols.PackageSymbol{}, nil) 40 | } 41 | 42 | func CreateBoundMakeArrayExpressionNode(baseType symbols.TypeSymbol, length BoundExpressionNode, src nodes.SyntaxNode) BoundMakeArrayExpressionNode { 43 | return BoundMakeArrayExpressionNode{ 44 | BaseType: baseType, 45 | Length: length, 46 | IsLiteral: false, 47 | UnboundSource: src, 48 | } 49 | } 50 | 51 | func CreateBoundMakeArrayExpressionNodeLiteral(baseType symbols.TypeSymbol, literals []BoundExpressionNode, src nodes.SyntaxNode) BoundMakeArrayExpressionNode { 52 | return BoundMakeArrayExpressionNode{ 53 | BaseType: baseType, 54 | Literals: literals, 55 | IsLiteral: true, 56 | UnboundSource: src, 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /nodes/boundnodes/expr-boundMakeExpression.go: -------------------------------------------------------------------------------- 1 | package boundnodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/nodes" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | "github.com/ReCT-Lang/ReCT-Go-Compiler/symbols" 8 | ) 9 | 10 | type BoundMakeExpressionNode struct { 11 | BoundExpressionNode 12 | 13 | BaseType symbols.ClassSymbol 14 | Arguments []BoundExpressionNode 15 | 16 | UnboundSource nodes.SyntaxNode 17 | } 18 | 19 | func (BoundMakeExpressionNode) NodeType() BoundType { return BoundMakeExpression } 20 | 21 | func (node BoundMakeExpressionNode) Print(indent string) { 22 | print.PrintC(print.Yellow, indent+"└ BoundMakeExpressionNode") 23 | fmt.Println(indent + " └ Type: ") 24 | node.BaseType.Print(indent + " ") 25 | fmt.Println(indent + " └ Arguments: ") 26 | for _, v := range node.Arguments { 27 | v.Print(indent + " ") 28 | } 29 | } 30 | 31 | func (node BoundMakeExpressionNode) Source() nodes.SyntaxNode { 32 | return node.UnboundSource 33 | } 34 | 35 | func (BoundMakeExpressionNode) IsPersistent() bool { return false } 36 | 37 | // implement the expression node interface 38 | func (node BoundMakeExpressionNode) Type() symbols.TypeSymbol { 39 | return node.BaseType.Type 40 | } 41 | 42 | func CreateBoundMakeExpressionNode(baseType symbols.ClassSymbol, args []BoundExpressionNode, src nodes.SyntaxNode) BoundMakeExpressionNode { 43 | return BoundMakeExpressionNode{ 44 | BaseType: baseType, 45 | Arguments: args, 46 | UnboundSource: src, 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /nodes/boundnodes/expr-boundMakeStructExpression.go: -------------------------------------------------------------------------------- 1 | package boundnodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/nodes" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | "github.com/ReCT-Lang/ReCT-Go-Compiler/symbols" 8 | ) 9 | 10 | type BoundMakeStructExpressionNode struct { 11 | BoundExpressionNode 12 | 13 | StructType symbols.TypeSymbol 14 | Literals []BoundExpressionNode 15 | 16 | UnboundSource nodes.SyntaxNode 17 | } 18 | 19 | func (BoundMakeStructExpressionNode) NodeType() BoundType { return BoundMakeStructExpression } 20 | 21 | func (node BoundMakeStructExpressionNode) Print(indent string) { 22 | print.PrintC(print.Yellow, indent+"└ BoundMakeStructExpressionNode") 23 | fmt.Println(indent + " └ Type: ") 24 | node.StructType.Print(indent + " ") 25 | //fmt.Println(indent + " └ Length: ") 26 | //node.Length.Print(indent + " ") 27 | } 28 | 29 | func (node BoundMakeStructExpressionNode) Source() nodes.SyntaxNode { 30 | return node.UnboundSource 31 | } 32 | 33 | func (BoundMakeStructExpressionNode) IsPersistent() bool { return false } 34 | 35 | // implement the expression node interface 36 | func (node BoundMakeStructExpressionNode) Type() symbols.TypeSymbol { 37 | return node.StructType 38 | } 39 | 40 | func CreateBoundMakeStructExpressionNode(structType symbols.TypeSymbol, literals []BoundExpressionNode, src nodes.SyntaxNode) BoundMakeStructExpressionNode { 41 | return BoundMakeStructExpressionNode{ 42 | StructType: structType, 43 | Literals: literals, 44 | UnboundSource: src, 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /nodes/boundnodes/expr-boundPackageCallExpression.go: -------------------------------------------------------------------------------- 1 | package boundnodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/nodes" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | "github.com/ReCT-Lang/ReCT-Go-Compiler/symbols" 8 | ) 9 | 10 | type BoundPackageCallExpressionNode struct { 11 | BoundExpressionNode 12 | 13 | Package symbols.PackageSymbol 14 | Function symbols.FunctionSymbol 15 | Arguments []BoundExpressionNode 16 | 17 | UnboundSource nodes.SyntaxNode 18 | } 19 | 20 | func (BoundPackageCallExpressionNode) NodeType() BoundType { return BoundPackageCallExpression } 21 | func (node BoundPackageCallExpressionNode) Print(indent string) { 22 | print.PrintC(print.Yellow, indent+"└ BoundPackageCallExpressionNode") 23 | node.Package.Print(indent) 24 | node.Function.Print(indent) 25 | fmt.Println(indent + " └ Arguments: ") 26 | for _, arg := range node.Arguments { 27 | arg.Print(indent + " ") 28 | } 29 | } 30 | 31 | func (node BoundPackageCallExpressionNode) Source() nodes.SyntaxNode { 32 | return node.UnboundSource 33 | } 34 | 35 | func (BoundPackageCallExpressionNode) IsPersistent() bool { return false } 36 | 37 | // implement the expression node interface 38 | func (node BoundPackageCallExpressionNode) Type() symbols.TypeSymbol { return node.Function.Type } 39 | 40 | func CreateBoundPackageCallExpressionNode(pack symbols.PackageSymbol, function symbols.FunctionSymbol, args []BoundExpressionNode, src nodes.SyntaxNode) BoundPackageCallExpressionNode { 41 | return BoundPackageCallExpressionNode{ 42 | Package: pack, 43 | Function: function, 44 | Arguments: args, 45 | UnboundSource: src, 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /nodes/boundnodes/expr-boundReferenceExpression.go: -------------------------------------------------------------------------------- 1 | package boundnodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/nodes" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | "github.com/ReCT-Lang/ReCT-Go-Compiler/symbols" 8 | ) 9 | 10 | type BoundReferenceExpressionNode struct { 11 | BoundExpressionNode 12 | 13 | Expression BoundExpressionNode 14 | UnboundSource nodes.SyntaxNode 15 | } 16 | 17 | func (BoundReferenceExpressionNode) NodeType() BoundType { return BoundReferenceExpression } 18 | 19 | func (node BoundReferenceExpressionNode) Source() nodes.SyntaxNode { 20 | return node.UnboundSource 21 | } 22 | 23 | func (node BoundReferenceExpressionNode) Print(indent string) { 24 | print.PrintC(print.Yellow, indent+"└ BoundReferenceExpressionNode") 25 | fmt.Println(indent + " └ Expression: ") 26 | node.Expression.Print(indent + " ") 27 | } 28 | 29 | func (node BoundReferenceExpressionNode) IsPersistent() bool { return false } 30 | 31 | // implement the expression node interface 32 | func (node BoundReferenceExpressionNode) Type() symbols.TypeSymbol { 33 | return symbols.CreateTypeSymbol("pointer", []symbols.TypeSymbol{node.Expression.Type()}, false, false, false, symbols.PackageSymbol{}, nil) 34 | } 35 | 36 | func CreateBoundReferenceExpressionNode(expression BoundExpressionNode, src nodes.SyntaxNode) BoundReferenceExpressionNode { 37 | return BoundReferenceExpressionNode{ 38 | Expression: expression, 39 | UnboundSource: src, 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /nodes/boundnodes/expr-boundThisExpression.go: -------------------------------------------------------------------------------- 1 | package boundnodes 2 | 3 | import ( 4 | "github.com/ReCT-Lang/ReCT-Go-Compiler/nodes" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/symbols" 7 | ) 8 | 9 | type BoundThisExpressionNode struct { 10 | BoundExpressionNode 11 | 12 | Class symbols.ClassSymbol 13 | UnboundSource nodes.SyntaxNode 14 | } 15 | 16 | func (BoundThisExpressionNode) NodeType() BoundType { return BoundThisExpression } 17 | 18 | func (node BoundThisExpressionNode) Print(indent string) { 19 | print.PrintC(print.Yellow, indent+"└ BoundThisExpressionNode") 20 | } 21 | 22 | func (node BoundThisExpressionNode) Source() nodes.SyntaxNode { 23 | return node.UnboundSource 24 | } 25 | 26 | func (BoundThisExpressionNode) IsPersistent() bool { return true } 27 | 28 | // implement the expression node interface 29 | func (node BoundThisExpressionNode) Type() symbols.TypeSymbol { return node.Class.Type } 30 | 31 | func CreateBoundThisExpressionNode(class symbols.ClassSymbol, src nodes.SyntaxNode) BoundThisExpressionNode { 32 | return BoundThisExpressionNode{ 33 | Class: class, 34 | UnboundSource: src, 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /nodes/boundnodes/expr-boundTypeCallExpression.go: -------------------------------------------------------------------------------- 1 | package boundnodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/nodes" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | "github.com/ReCT-Lang/ReCT-Go-Compiler/symbols" 8 | ) 9 | 10 | type BoundTypeCallExpressionNode struct { 11 | BoundExpressionNode 12 | 13 | Base BoundExpressionNode 14 | Function symbols.TypeFunctionSymbol 15 | Arguments []BoundExpressionNode 16 | 17 | UnboundSource nodes.SyntaxNode 18 | } 19 | 20 | // implement node type from interface 21 | func (BoundTypeCallExpressionNode) NodeType() BoundType { return BoundTypeCallExpression } 22 | 23 | // implement the expression node interface 24 | func (node BoundTypeCallExpressionNode) Type() symbols.TypeSymbol { return node.Function.Type } 25 | 26 | func (node BoundTypeCallExpressionNode) Source() nodes.SyntaxNode { 27 | return node.UnboundSource 28 | } 29 | 30 | // node print function 31 | func (node BoundTypeCallExpressionNode) Print(indent string) { 32 | print.PrintC(print.Yellow, indent+"└ BoundTypeCallExpressionNode") 33 | fmt.Println(indent + " └ Base: ") 34 | node.Base.Print(indent + " ") 35 | fmt.Println(indent + " └ Function: ") 36 | node.Function.Print(indent + " ") 37 | fmt.Println(indent + " └ Arguments: ") 38 | for _, arg := range node.Arguments { 39 | arg.Print(indent + " ") 40 | } 41 | } 42 | 43 | func (BoundTypeCallExpressionNode) IsPersistent() bool { return false } 44 | 45 | // "constructor" / ooga booga OOP cave man brain 46 | func CreateBoundTypeCallExpressionNode( 47 | base BoundExpressionNode, 48 | callId symbols.TypeFunctionSymbol, 49 | args []BoundExpressionNode, 50 | src nodes.SyntaxNode, 51 | ) BoundTypeCallExpressionNode { 52 | return BoundTypeCallExpressionNode{ 53 | Base: base, 54 | Function: callId, 55 | Arguments: args, 56 | UnboundSource: src, 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /nodes/boundnodes/expr-boundUnaryExpression.go: -------------------------------------------------------------------------------- 1 | package boundnodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/nodes" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | "github.com/ReCT-Lang/ReCT-Go-Compiler/symbols" 8 | ) 9 | 10 | type BoundUnaryExpressionNode struct { 11 | BoundExpressionNode 12 | 13 | Op BoundUnaryOperator 14 | Expression BoundExpressionNode 15 | 16 | UnboundSource nodes.SyntaxNode 17 | } 18 | 19 | func (BoundUnaryExpressionNode) NodeType() BoundType { return BoundUnaryExpression } 20 | 21 | func (node BoundUnaryExpressionNode) Print(indent string) { 22 | print.PrintC(print.Yellow, indent+"└ BoundUnaryExpressionNode") 23 | fmt.Printf("%s └ Operator: %s\n", indent, node.Op.OperatorKind) 24 | fmt.Println(indent + " └ Expression: ") 25 | node.Expression.Print(indent + " ") 26 | } 27 | 28 | func (node BoundUnaryExpressionNode) Source() nodes.SyntaxNode { 29 | return node.UnboundSource 30 | } 31 | 32 | func (BoundUnaryExpressionNode) IsPersistent() bool { return false } 33 | 34 | // implement the expression node interface 35 | func (node BoundUnaryExpressionNode) Type() symbols.TypeSymbol { return node.Op.ResultType } 36 | 37 | func CreateBoundUnaryExpressionNode(op BoundUnaryOperator, expression BoundExpressionNode, src nodes.SyntaxNode) BoundUnaryExpressionNode { 38 | return BoundUnaryExpressionNode{ 39 | Op: op, 40 | Expression: expression, 41 | UnboundSource: src, 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /nodes/boundnodes/expr-boundVariableExpression.go: -------------------------------------------------------------------------------- 1 | package boundnodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/nodes" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | "github.com/ReCT-Lang/ReCT-Go-Compiler/symbols" 8 | ) 9 | 10 | type BoundVariableExpressionNode struct { 11 | BoundExpressionNode 12 | 13 | InMain bool 14 | Variable symbols.VariableSymbol 15 | UnboundSource nodes.SyntaxNode 16 | } 17 | 18 | func (BoundVariableExpressionNode) NodeType() BoundType { return BoundVariableExpression } 19 | 20 | func (node BoundVariableExpressionNode) Print(indent string) { 21 | print.PrintC(print.Yellow, indent+"└ BoundVariableExpressionNode") 22 | fmt.Println(indent + " └ Variable: ") 23 | node.Variable.Print(indent + " ") 24 | } 25 | 26 | func (node BoundVariableExpressionNode) Source() nodes.SyntaxNode { 27 | return node.UnboundSource 28 | } 29 | 30 | func (BoundVariableExpressionNode) IsPersistent() bool { return true } 31 | 32 | // implement the expression node interface 33 | func (node BoundVariableExpressionNode) Type() symbols.TypeSymbol { return node.Variable.VarType() } 34 | 35 | func CreateBoundVariableExpressionNode(variable symbols.VariableSymbol, inMain bool, src nodes.SyntaxNode) BoundVariableExpressionNode { 36 | return BoundVariableExpressionNode{ 37 | Variable: variable, 38 | InMain: inMain, 39 | UnboundSource: src, 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /nodes/boundnodes/expr-ternaryExpression.go: -------------------------------------------------------------------------------- 1 | package boundnodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/nodes" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | "github.com/ReCT-Lang/ReCT-Go-Compiler/symbols" 8 | ) 9 | 10 | type BoundTernaryExpressionNode struct { 11 | BoundExpressionNode 12 | 13 | Condition BoundExpressionNode 14 | If BoundExpressionNode 15 | Else BoundExpressionNode 16 | Tmp symbols.LocalVariableSymbol 17 | 18 | IfLabel BoundLabel 19 | ElseLabel BoundLabel 20 | EndLabel BoundLabel 21 | 22 | UnboundSource nodes.SyntaxNode 23 | } 24 | 25 | func (BoundTernaryExpressionNode) NodeType() BoundType { return BoundTernaryExpression } 26 | 27 | func (node BoundTernaryExpressionNode) Print(indent string) { 28 | print.PrintC(print.Yellow, indent+"└ BoundTernaryExpressionNode") 29 | fmt.Println(indent + " └ Condition: ") 30 | node.Condition.Print(indent + " ") 31 | fmt.Println(indent + " └ If: ") 32 | node.If.Print(indent + " ") 33 | fmt.Println(indent + " └ Else: ") 34 | node.Else.Print(indent + " ") 35 | } 36 | 37 | func (node BoundTernaryExpressionNode) Source() nodes.SyntaxNode { 38 | return node.UnboundSource 39 | } 40 | 41 | func (node BoundTernaryExpressionNode) IsPersistent() bool { 42 | return node.If.IsPersistent() || node.Else.IsPersistent() 43 | } 44 | 45 | // implement the expression node interface 46 | func (node BoundTernaryExpressionNode) Type() symbols.TypeSymbol { return node.If.Type() } 47 | 48 | func CreateBoundTernaryExpressionNode(cond BoundExpressionNode, left BoundExpressionNode, right BoundExpressionNode, tmp symbols.LocalVariableSymbol, src nodes.SyntaxNode) BoundTernaryExpressionNode { 49 | return BoundTernaryExpressionNode{ 50 | Condition: cond, 51 | If: left, 52 | Else: right, 53 | Tmp: tmp, 54 | UnboundSource: src, 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /nodes/boundnodes/stmt-boundBlockStatement.go: -------------------------------------------------------------------------------- 1 | package boundnodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/nodes" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | ) 8 | 9 | type BoundBlockStatementNode struct { 10 | BoundStatementNode 11 | 12 | Statements []BoundStatementNode 13 | UnboundSource nodes.SyntaxNode 14 | } 15 | 16 | // implement the interface 17 | func (BoundBlockStatementNode) NodeType() BoundType { return BoundBlockStatement } 18 | func (node BoundBlockStatementNode) Print(indent string) { 19 | print.PrintC(print.Green, indent+"└ BoundBlockStatementNode") 20 | fmt.Println(indent + " └ Statements: ") 21 | 22 | for _, stmt := range node.Statements { 23 | stmt.Print(indent + " ") 24 | } 25 | } 26 | 27 | func (node BoundBlockStatementNode) Source() nodes.SyntaxNode { 28 | return node.UnboundSource 29 | } 30 | 31 | // constructor 32 | func CreateBoundBlockStatementNode(stmts []BoundStatementNode, src nodes.SyntaxNode) BoundBlockStatementNode { 33 | return BoundBlockStatementNode{ 34 | Statements: stmts, 35 | UnboundSource: src, 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /nodes/boundnodes/stmt-boundConditionalGotoStatement.go: -------------------------------------------------------------------------------- 1 | package boundnodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/nodes" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | ) 8 | 9 | type BoundConditionalGotoStatementNode struct { 10 | BoundStatementNode 11 | 12 | Condition BoundExpressionNode 13 | IfLabel BoundLabel 14 | ElseLabel BoundLabel 15 | 16 | UnboundSource nodes.SyntaxNode 17 | } 18 | 19 | // implement the interface 20 | func (BoundConditionalGotoStatementNode) NodeType() BoundType { return BoundConditionalGotoStatement } 21 | func (node BoundConditionalGotoStatementNode) Print(indent string) { 22 | print.PrintC(print.Green, indent+"└ BoundConditionalGotoStatementNode") 23 | fmt.Println(indent + " └ Condition:") 24 | node.Condition.Print(indent + " ") 25 | fmt.Printf("%s └ IfLabel: %s\n", indent, node.IfLabel) 26 | fmt.Printf("%s └ ElseLabel: %s\n", indent, node.ElseLabel) 27 | } 28 | 29 | func (node BoundConditionalGotoStatementNode) Source() nodes.SyntaxNode { 30 | return node.UnboundSource 31 | } 32 | 33 | // constructor 34 | func CreateBoundConditionalGotoStatementNode(condition BoundExpressionNode, ifLabel BoundLabel, elseLabel BoundLabel, src nodes.SyntaxNode) BoundConditionalGotoStatementNode { 35 | return BoundConditionalGotoStatementNode{ 36 | Condition: condition, 37 | IfLabel: ifLabel, 38 | ElseLabel: elseLabel, 39 | UnboundSource: src, 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /nodes/boundnodes/stmt-boundExpressionStatement.go: -------------------------------------------------------------------------------- 1 | package boundnodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/nodes" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | ) 8 | 9 | type BoundExpressionStatementNode struct { 10 | BoundStatementNode 11 | 12 | Expression BoundExpressionNode 13 | UnboundSource nodes.SyntaxNode 14 | } 15 | 16 | // implement the interface 17 | func (BoundExpressionStatementNode) NodeType() BoundType { return BoundExpressionStatement } 18 | func (node BoundExpressionStatementNode) Print(indent string) { 19 | print.PrintC(print.Green, indent+"└ BoundExpressionStatementNode") 20 | fmt.Println(indent + " └ Expression:") 21 | node.Expression.Print(indent + " ") 22 | } 23 | 24 | func (node BoundExpressionStatementNode) Source() nodes.SyntaxNode { 25 | return node.UnboundSource 26 | } 27 | 28 | // constructor 29 | func CreateBoundExpressionStatementNode(expr BoundExpressionNode, src nodes.SyntaxNode) BoundExpressionStatementNode { 30 | return BoundExpressionStatementNode{ 31 | Expression: expr, 32 | UnboundSource: src, 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /nodes/boundnodes/stmt-boundForStatement.go: -------------------------------------------------------------------------------- 1 | package boundnodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/nodes" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | ) 8 | 9 | type BoundForStatementNode struct { 10 | BoundLoopStatementNode 11 | 12 | Variable BoundVariableDeclarationStatementNode 13 | Condition BoundExpressionNode 14 | Action BoundStatementNode 15 | 16 | Body BoundStatementNode 17 | BreakLabel BoundLabel 18 | ContinueLabel BoundLabel 19 | 20 | UnboundSource nodes.SyntaxNode 21 | } 22 | 23 | // implement the interface 24 | func (BoundForStatementNode) NodeType() BoundType { return BoundForStatement } 25 | func (node BoundForStatementNode) Print(indent string) { 26 | print.PrintC(print.Green, indent+"└ BoundForStatementNode") 27 | fmt.Println(indent + " └ Variable: ") 28 | node.Variable.Print(indent + " ") 29 | fmt.Println(indent + " └ Condition: ") 30 | node.Condition.Print(indent + " ") 31 | fmt.Println(indent + " └ Action: ") 32 | node.Action.Print(indent + " ") 33 | fmt.Println(indent + " └ Body: ") 34 | node.Body.Print(indent + " ") 35 | 36 | fmt.Printf("%s └ BreakLabel: %s\n", indent, node.BreakLabel) 37 | fmt.Printf("%s └ ContinueLabel: %s\n", indent, node.ContinueLabel) 38 | } 39 | 40 | func (node BoundForStatementNode) Source() nodes.SyntaxNode { 41 | return node.UnboundSource 42 | } 43 | 44 | func (node BoundForStatementNode) LoopBreakLabel() BoundLabel { return node.BreakLabel } 45 | func (node BoundForStatementNode) LoopContinueLabel() BoundLabel { return node.ContinueLabel } 46 | 47 | // constructor 48 | func CreateBoundForStatementNode(variable BoundVariableDeclarationStatementNode, cond BoundExpressionNode, action BoundStatementNode, body BoundStatementNode, breakLabel BoundLabel, continueLabel BoundLabel, src nodes.SyntaxNode) BoundForStatementNode { 49 | return BoundForStatementNode{ 50 | Variable: variable, 51 | Condition: cond, 52 | Action: action, 53 | Body: body, 54 | BreakLabel: breakLabel, 55 | ContinueLabel: continueLabel, 56 | UnboundSource: src, 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /nodes/boundnodes/stmt-boundFromToStatement.go: -------------------------------------------------------------------------------- 1 | package boundnodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/nodes" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | "github.com/ReCT-Lang/ReCT-Go-Compiler/symbols" 8 | ) 9 | 10 | type BoundFromToStatementNode struct { 11 | BoundLoopStatementNode 12 | 13 | Variable symbols.VariableSymbol 14 | LowerBound BoundExpressionNode 15 | UpperBound BoundExpressionNode 16 | Body BoundStatementNode 17 | BreakLabel BoundLabel 18 | ContinueLabel BoundLabel 19 | 20 | UnboundSource nodes.SyntaxNode 21 | } 22 | 23 | // implement the interface 24 | func (BoundFromToStatementNode) NodeType() BoundType { return BoundFromToStatement } 25 | func (node BoundFromToStatementNode) Print(indent string) { 26 | print.PrintC(print.Green, indent+"└ BoundFromToStatementNode") 27 | fmt.Println(indent + " └ Variable: ") 28 | node.Variable.Print(indent + " ") 29 | fmt.Println(indent + " └ LowerBound: ") 30 | node.LowerBound.Print(indent + " ") 31 | fmt.Println(indent + " └ UpperBound: ") 32 | node.UpperBound.Print(indent + " ") 33 | fmt.Println(indent + " └ Body: ") 34 | node.Body.Print(indent + " ") 35 | 36 | fmt.Printf("%s └ BreakLabel: %s\n", indent, node.BreakLabel) 37 | fmt.Printf("%s └ ContinueLabel: %s\n", indent, node.ContinueLabel) 38 | } 39 | 40 | func (node BoundFromToStatementNode) Source() nodes.SyntaxNode { 41 | return node.UnboundSource 42 | } 43 | 44 | func (node BoundFromToStatementNode) LoopBreakLabel() BoundLabel { return node.BreakLabel } 45 | func (node BoundFromToStatementNode) LoopContinueLabel() BoundLabel { return node.ContinueLabel } 46 | 47 | // constructor 48 | func CreateBoundFromToStatementNode(variable symbols.VariableSymbol, lower BoundExpressionNode, upper BoundExpressionNode, body BoundStatementNode, breakLabel BoundLabel, continueLabel BoundLabel, src nodes.SyntaxNode) BoundFromToStatementNode { 49 | return BoundFromToStatementNode{ 50 | Variable: variable, 51 | LowerBound: lower, 52 | UpperBound: upper, 53 | Body: body, 54 | BreakLabel: breakLabel, 55 | ContinueLabel: continueLabel, 56 | UnboundSource: src, 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /nodes/boundnodes/stmt-boundGotoStatement.go: -------------------------------------------------------------------------------- 1 | package boundnodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/nodes" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | ) 8 | 9 | type BoundGotoStatementNode struct { 10 | BoundStatementNode 11 | 12 | Label BoundLabel 13 | UnboundSource nodes.SyntaxNode 14 | } 15 | 16 | // implement the interface 17 | func (BoundGotoStatementNode) NodeType() BoundType { return BoundGotoStatement } 18 | func (node BoundGotoStatementNode) Print(indent string) { 19 | print.PrintC(print.Green, indent+"└ BoundGotoStatementNode") 20 | fmt.Printf("%s └ Label: %s\n", indent, node.Label) 21 | } 22 | 23 | func (node BoundGotoStatementNode) Source() nodes.SyntaxNode { 24 | return node.UnboundSource 25 | } 26 | 27 | // constructor 28 | func CreateBoundGotoStatementNode(label BoundLabel, src nodes.SyntaxNode) BoundGotoStatementNode { 29 | return BoundGotoStatementNode{ 30 | Label: label, 31 | UnboundSource: src, 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /nodes/boundnodes/stmt-boundIfStatement.go: -------------------------------------------------------------------------------- 1 | package boundnodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/nodes" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | ) 8 | 9 | type BoundIfStatementNode struct { 10 | BoundStatementNode 11 | 12 | Condition BoundExpressionNode 13 | ThenStatement BoundStatementNode 14 | ElseStatement BoundStatementNode 15 | 16 | UnboundSource nodes.SyntaxNode 17 | } 18 | 19 | // implement the interface 20 | func (BoundIfStatementNode) NodeType() BoundType { return BoundIfStatement } 21 | func (node BoundIfStatementNode) Print(indent string) { 22 | print.PrintC(print.Green, indent+"└ BoundIfStatementNode") 23 | fmt.Println(indent + " └ Condition: ") 24 | node.Condition.Print(indent + " ") 25 | fmt.Println(indent + " └ ThenStatement: ") 26 | node.ThenStatement.Print(indent + " ") 27 | 28 | if node.ElseStatement != nil { 29 | fmt.Println(indent + " └ ElseStatement: ") 30 | node.ThenStatement.Print(indent + " ") 31 | } else { 32 | fmt.Println(indent + " └ ElseStatement: none") 33 | } 34 | } 35 | 36 | func (node BoundIfStatementNode) Source() nodes.SyntaxNode { 37 | return node.UnboundSource 38 | } 39 | 40 | // constructor 41 | func CreateBoundIfStatementNode(cond BoundExpressionNode, thenStmt BoundStatementNode, elseStmt BoundStatementNode, src nodes.SyntaxNode) BoundIfStatementNode { 42 | return BoundIfStatementNode{ 43 | Condition: cond, 44 | ThenStatement: thenStmt, 45 | ElseStatement: elseStmt, 46 | UnboundSource: src, 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /nodes/boundnodes/stmt-boundLabelStatement.go: -------------------------------------------------------------------------------- 1 | package boundnodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/nodes" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | ) 8 | 9 | type BoundLabelStatementNode struct { 10 | BoundStatementNode 11 | 12 | Label BoundLabel 13 | UnboundSource nodes.SyntaxNode 14 | } 15 | 16 | // implement the interface 17 | func (BoundLabelStatementNode) NodeType() BoundType { return BoundLabelStatement } 18 | func (node BoundLabelStatementNode) Print(indent string) { 19 | print.PrintC(print.Green, indent+"└ BoundLabelStatementNode") 20 | fmt.Printf("%s └ Label: %s\n", indent, node.Label) 21 | } 22 | 23 | func (node BoundLabelStatementNode) Source() nodes.SyntaxNode { 24 | return node.UnboundSource 25 | } 26 | 27 | // constructor 28 | func CreateBoundLabelStatementNode(label BoundLabel, src nodes.SyntaxNode) BoundLabelStatementNode { 29 | return BoundLabelStatementNode{ 30 | Label: label, 31 | UnboundSource: src, 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /nodes/boundnodes/stmt-boundReturnStatement.go: -------------------------------------------------------------------------------- 1 | package boundnodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/nodes" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | ) 8 | 9 | type BoundReturnStatementNode struct { 10 | BoundStatementNode 11 | 12 | Expression BoundExpressionNode 13 | UnboundSource nodes.SyntaxNode 14 | } 15 | 16 | // implement the interface 17 | func (BoundReturnStatementNode) NodeType() BoundType { return BoundReturnStatement } 18 | func (node BoundReturnStatementNode) Print(indent string) { 19 | print.PrintC(print.Green, indent+"└ BoundReturnStatementNode") 20 | if node.Expression == nil { 21 | fmt.Println(indent + " └ Expression: none") 22 | } else { 23 | fmt.Println(indent + " └ Expression:") 24 | node.Expression.Print(indent + " ") 25 | } 26 | } 27 | 28 | func (node BoundReturnStatementNode) Source() nodes.SyntaxNode { 29 | return node.UnboundSource 30 | } 31 | 32 | // constructor 33 | func CreateBoundReturnStatementNode(expr BoundExpressionNode, src nodes.SyntaxNode) BoundReturnStatementNode { 34 | return BoundReturnStatementNode{ 35 | Expression: expr, 36 | UnboundSource: src, 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /nodes/boundnodes/stmt-boundVariableDeclaration.go: -------------------------------------------------------------------------------- 1 | package boundnodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/nodes" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | "github.com/ReCT-Lang/ReCT-Go-Compiler/symbols" 8 | ) 9 | 10 | type BoundVariableDeclarationStatementNode struct { 11 | BoundStatementNode 12 | 13 | Variable symbols.VariableSymbol 14 | Initializer BoundExpressionNode 15 | 16 | UnboundSource nodes.SyntaxNode 17 | } 18 | 19 | // implement the interface 20 | func (BoundVariableDeclarationStatementNode) NodeType() BoundType { return BoundVariableDeclaration } 21 | func (node BoundVariableDeclarationStatementNode) Print(indent string) { 22 | print.PrintC(print.Green, indent+"└ BoundVariableDeclarationStatementNode") 23 | fmt.Println(indent + " └ Variable: ") 24 | node.Variable.Print(indent + " ") 25 | fmt.Println(indent + " └ Initializer: ") 26 | if node.Initializer != nil { 27 | node.Initializer.Print(indent + " ") 28 | } else { 29 | fmt.Println(indent + " none") 30 | } 31 | } 32 | 33 | func (node BoundVariableDeclarationStatementNode) Source() nodes.SyntaxNode { 34 | return node.UnboundSource 35 | } 36 | 37 | // constructor 38 | func CreateBoundVariableDeclarationStatementNode(variable symbols.VariableSymbol, init BoundExpressionNode, src nodes.SyntaxNode) BoundVariableDeclarationStatementNode { 39 | return BoundVariableDeclarationStatementNode{ 40 | Variable: variable, 41 | Initializer: init, 42 | UnboundSource: src, 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /nodes/boundnodes/stmt-boundWhileStatement.go: -------------------------------------------------------------------------------- 1 | package boundnodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/nodes" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | ) 8 | 9 | type BoundWhileStatementNode struct { 10 | BoundLoopStatementNode 11 | 12 | Condition BoundExpressionNode 13 | Body BoundStatementNode 14 | BreakLabel BoundLabel 15 | ContinueLabel BoundLabel 16 | 17 | UnboundSource nodes.SyntaxNode 18 | } 19 | 20 | // implement the interface 21 | func (BoundWhileStatementNode) NodeType() BoundType { return BoundWhileStatement } 22 | func (node BoundWhileStatementNode) Print(indent string) { 23 | print.PrintC(print.Green, indent+"└ BoundWhileStatementNode") 24 | fmt.Println(indent + " └ Condition: ") 25 | node.Condition.Print(indent + " ") 26 | fmt.Println(indent + " └ Body: ") 27 | node.Body.Print(indent + " ") 28 | 29 | fmt.Printf("%s └ BreakLabel: %s\n", indent, node.BreakLabel) 30 | fmt.Printf("%s └ ContinueLabel: %s\n", indent, node.ContinueLabel) 31 | } 32 | 33 | func (node BoundWhileStatementNode) Source() nodes.SyntaxNode { 34 | return node.UnboundSource 35 | } 36 | 37 | func (node BoundWhileStatementNode) LoopBreakLabel() BoundLabel { return node.BreakLabel } 38 | func (node BoundWhileStatementNode) LoopContinueLabel() BoundLabel { return node.ContinueLabel } 39 | 40 | // constructor 41 | func CreateBoundWhileStatementNode(cond BoundExpressionNode, body BoundStatementNode, breakLabel BoundLabel, continueLabel BoundLabel, src nodes.SyntaxNode) BoundWhileStatementNode { 42 | return BoundWhileStatementNode{ 43 | Condition: cond, 44 | Body: body, 45 | BreakLabel: breakLabel, 46 | ContinueLabel: continueLabel, 47 | UnboundSource: src, 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /nodes/clause-elseClause.go: -------------------------------------------------------------------------------- 1 | package nodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/lexer" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | ) 8 | 9 | // basic global statement member 10 | type ElseClauseNode struct { 11 | SyntaxNode 12 | 13 | ClauseIsSet bool 14 | ElseKeyword lexer.Token 15 | ElseStatement StatementNode 16 | } 17 | 18 | // implement node type from interface 19 | func (ElseClauseNode) NodeType() NodeType { return ElseClause } 20 | 21 | // Position returns the starting line and column, and the total length of the statement 22 | // The starting line and column aren't always the absolute beginning of the statement just what's most 23 | // convenient. 24 | func (node ElseClauseNode) Span() print.TextSpan { 25 | if node.ClauseIsSet { 26 | return node.ElseKeyword.Span.SpanBetween(node.ElseStatement.Span()) 27 | } else { 28 | return print.TextSpan{} // empty 29 | } 30 | } 31 | 32 | // node print function 33 | func (node ElseClauseNode) Print(indent string) { 34 | print.PrintC(print.Green, indent+"└ ElseClauseNode") 35 | fmt.Printf("%s └ Keyword: %s\n", indent, node.ElseKeyword.Kind) 36 | fmt.Println(indent + " └ Statement: ") 37 | node.ElseStatement.Print(indent + " ") 38 | 39 | } 40 | 41 | // "constructor" / ooga booga OOP cave man brain 42 | func CreateElseClauseNode(kw lexer.Token, stmt StatementNode) ElseClauseNode { 43 | return ElseClauseNode{ 44 | ElseKeyword: kw, 45 | ElseStatement: stmt, 46 | ClauseIsSet: true, 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /nodes/clause-typeClause.go: -------------------------------------------------------------------------------- 1 | package nodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/lexer" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | ) 8 | 9 | // basic global statement member 10 | type TypeClauseNode struct { 11 | SyntaxNode 12 | 13 | ClauseIsSet bool 14 | 15 | Package *lexer.Token 16 | TypeIdentifier lexer.Token 17 | SubClauses []TypeClauseNode 18 | ClosingBracket lexer.Token 19 | } 20 | 21 | // implement node type from interface 22 | func (TypeClauseNode) NodeType() NodeType { return TypeClause } 23 | 24 | func (node TypeClauseNode) Span() print.TextSpan { 25 | if node.ClauseIsSet { 26 | span := node.TypeIdentifier.Span 27 | span = span.SpanBetween(node.ClosingBracket.Span) 28 | 29 | return span 30 | } else { 31 | return print.TextSpan{} 32 | } 33 | } 34 | 35 | // node print function 36 | func (node TypeClauseNode) Print(indent string) { 37 | print.PrintC(print.Green, indent+"└ TypeClauseNode") 38 | fmt.Printf("%s └ Type: %s\n", indent, node.TypeIdentifier.Value) 39 | 40 | } 41 | 42 | // "constructor" / ooga booga OOP cave man brain 43 | func CreateTypeClauseNode(pack *lexer.Token, id lexer.Token, subtypes []TypeClauseNode, bracket lexer.Token) TypeClauseNode { 44 | return TypeClauseNode{ 45 | ClauseIsSet: true, 46 | Package: pack, 47 | TypeIdentifier: id, 48 | SubClauses: subtypes, 49 | ClosingBracket: bracket, 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /nodes/expr-arrayAccessExpression.go: -------------------------------------------------------------------------------- 1 | package nodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/lexer" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | ) 8 | 9 | type ArrayAccessExpressionNode struct { 10 | ExpressionNode 11 | 12 | Base ExpressionNode 13 | Index ExpressionNode 14 | ClosingBracket lexer.Token 15 | } 16 | 17 | // implement node type from interface 18 | func (ArrayAccessExpressionNode) NodeType() NodeType { return ArrayAccessExpression } 19 | 20 | // Position returns the starting line and column, and the total length of the statement 21 | // The starting line and column aren't always the absolute beginning of the statement just what's most 22 | // convenient. 23 | func (node ArrayAccessExpressionNode) Span() print.TextSpan { 24 | return node.Base.Span().SpanBetween(node.ClosingBracket.Span) 25 | } 26 | 27 | // node print function 28 | func (node ArrayAccessExpressionNode) Print(indent string) { 29 | print.PrintC(print.Yellow, indent+"└ ArrayAccessExpressionNode") 30 | fmt.Println(indent + " └ Base: ") 31 | node.Base.Print(indent + " ") 32 | fmt.Println(indent + " └ Index: ") 33 | node.Index.Print(indent + " ") 34 | } 35 | 36 | // "constructor" / ooga booga OOP cave man brain 37 | func CreateArrayAccessExpressionNode(base ExpressionNode, index ExpressionNode) ArrayAccessExpressionNode { 38 | return ArrayAccessExpressionNode{ 39 | Base: base, 40 | Index: index, 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /nodes/expr-arrayAssignmentExpression.go: -------------------------------------------------------------------------------- 1 | package nodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 6 | ) 7 | 8 | type ArrayAssignmentExpressionNode struct { 9 | ExpressionNode 10 | 11 | Base ExpressionNode 12 | Index ExpressionNode 13 | Value ExpressionNode 14 | } 15 | 16 | // implement node type from interface 17 | func (ArrayAssignmentExpressionNode) NodeType() NodeType { return ArrayAssignmentExpression } 18 | 19 | // Position returns the starting line and column, and the total length of the statement 20 | // The starting line and column aren't always the absolute beginning of the statement just what's most 21 | // convenient. 22 | func (node ArrayAssignmentExpressionNode) Span() print.TextSpan { 23 | return node.Base.Span().SpanBetween(node.Value.Span()) 24 | } 25 | 26 | // node print function 27 | func (node ArrayAssignmentExpressionNode) Print(indent string) { 28 | print.PrintC(print.Yellow, indent+"└ ArrayAccessExpressionNode") 29 | fmt.Println(indent + " └ Base: ") 30 | node.Base.Print(indent + " ") 31 | fmt.Println(indent + " └ Index: ") 32 | node.Index.Print(indent + " ") 33 | } 34 | 35 | // "constructor" / ooga booga OOP cave man brain 36 | func CreateArrayAssignmentExpressionNode(base ExpressionNode, index ExpressionNode, value ExpressionNode) ArrayAssignmentExpressionNode { 37 | return ArrayAssignmentExpressionNode{ 38 | Base: base, 39 | Index: index, 40 | Value: value, 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /nodes/expr-assignmentExpression.go: -------------------------------------------------------------------------------- 1 | package nodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/lexer" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | ) 8 | 9 | type AssignmentExpressionNode struct { 10 | ExpressionNode 11 | 12 | InMain bool 13 | Identifier lexer.Token 14 | Expression ExpressionNode 15 | } 16 | 17 | // implement node type from interface 18 | func (AssignmentExpressionNode) NodeType() NodeType { return AssignmentExpression } 19 | 20 | // Position returns the starting line and column, and the total length of the statement 21 | // The starting line and column aren't always the absolute beginning of the statement just what's most 22 | // convenient. 23 | func (node AssignmentExpressionNode) Span() print.TextSpan { 24 | return node.Identifier.Span.SpanBetween(node.Expression.Span()) 25 | } 26 | 27 | // node print function 28 | func (node AssignmentExpressionNode) Print(indent string) { 29 | print.PrintC(print.Yellow, indent+"└ AssignmentExpressionNode") 30 | fmt.Printf("%s └ Identifier: %s\n", indent, node.Identifier.Value) 31 | fmt.Println(indent + " └ Expression: ") 32 | node.Expression.Print(indent + " ") 33 | } 34 | 35 | // "constructor" / ooga booga OOP cave man brain 36 | func CreateAssignmentExpressionNode(id lexer.Token, expr ExpressionNode) AssignmentExpressionNode { 37 | return AssignmentExpressionNode{ 38 | Identifier: id, 39 | Expression: expr, 40 | } 41 | } 42 | 43 | func CreateMainAssignmentExpressionNode(id lexer.Token, expr ExpressionNode) AssignmentExpressionNode { 44 | return AssignmentExpressionNode{ 45 | Identifier: id, 46 | Expression: expr, 47 | InMain: true, 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /nodes/expr-binaryExpression.go: -------------------------------------------------------------------------------- 1 | package nodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/lexer" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | ) 8 | 9 | type BinaryExpressionNode struct { 10 | ExpressionNode 11 | 12 | Left ExpressionNode 13 | Operator lexer.Token 14 | Right ExpressionNode 15 | } 16 | 17 | // implement node type from interface 18 | func (BinaryExpressionNode) NodeType() NodeType { return BinaryExpression } 19 | 20 | // Position returns the starting line and column, and the total length of the statement 21 | // The starting line and column aren't always the absolute beginning of the statement just what's most 22 | // convenient. 23 | func (node BinaryExpressionNode) Span() print.TextSpan { 24 | return node.Left.Span().SpanBetween(node.Right.Span()) 25 | } 26 | 27 | // node print function 28 | func (node BinaryExpressionNode) Print(indent string) { 29 | print.PrintC(print.Yellow, indent+"└ BinaryExpressionNode") 30 | fmt.Printf("%s └ Operator: %s\n", indent, node.Operator.Kind) 31 | fmt.Println(indent + " └ Left: ") 32 | node.Left.Print(indent + " ") 33 | fmt.Println(indent + " └ Right: ") 34 | node.Right.Print(indent + " ") 35 | } 36 | 37 | // "constructor" / ooga booga OOP cave man brain 38 | func CreateBinaryExpressionNode(op lexer.Token, left ExpressionNode, right ExpressionNode) BinaryExpressionNode { 39 | return BinaryExpressionNode{ 40 | Left: left, 41 | Operator: op, 42 | Right: right, 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /nodes/expr-callExpression.go: -------------------------------------------------------------------------------- 1 | package nodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/lexer" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | ) 8 | 9 | type CallExpressionNode struct { 10 | ExpressionNode 11 | 12 | InMain bool 13 | 14 | Identifier lexer.Token 15 | Arguments []ExpressionNode 16 | 17 | CastingType TypeClauseNode // if this call is actually a complex cast 18 | 19 | ClosingParenthesis lexer.Token 20 | } 21 | 22 | // implement node type from interface 23 | func (CallExpressionNode) NodeType() NodeType { return CallExpression } 24 | 25 | func (node CallExpressionNode) Span() print.TextSpan { 26 | if node.CastingType.ClauseIsSet { 27 | return node.CastingType.Span().SpanBetween(node.ClosingParenthesis.Span) 28 | } else { 29 | return node.Identifier.Span.SpanBetween(node.ClosingParenthesis.Span) 30 | } 31 | } 32 | 33 | // node print function 34 | func (node CallExpressionNode) Print(indent string) { 35 | print.PrintC(print.Yellow, indent+"└ CallExpressionNode") 36 | fmt.Printf("%s └ Identifier: %s\n", indent, node.Identifier.Value) 37 | 38 | fmt.Println(indent + " └ Arguments: ") 39 | for _, arg := range node.Arguments { 40 | arg.Print(indent + " ") 41 | } 42 | } 43 | 44 | // "constructor" / ooga booga OOP cave man brain 45 | func CreateCallExpressionNode(id lexer.Token, args []ExpressionNode, castClause TypeClauseNode, parenthesis lexer.Token) CallExpressionNode { 46 | return CallExpressionNode{ 47 | Identifier: id, 48 | Arguments: args, 49 | CastingType: castClause, 50 | ClosingParenthesis: parenthesis, 51 | } 52 | } 53 | 54 | func CreateMainCallExpressionNode(id lexer.Token, args []ExpressionNode, castClause TypeClauseNode, parenthesis lexer.Token) CallExpressionNode { 55 | return CallExpressionNode{ 56 | Identifier: id, 57 | Arguments: args, 58 | CastingType: castClause, 59 | ClosingParenthesis: parenthesis, 60 | InMain: true, 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /nodes/expr-classFieldAccessEpxression.go: -------------------------------------------------------------------------------- 1 | package nodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/lexer" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | ) 8 | 9 | type ClassFieldAccessExpressionNode struct { 10 | ExpressionNode 11 | 12 | Base ExpressionNode 13 | FieldIdentifier lexer.Token 14 | } 15 | 16 | // implement node type from interface 17 | func (ClassFieldAccessExpressionNode) NodeType() NodeType { return ClassFieldAccessExpression } 18 | 19 | // Position returns the starting line and column, and the total length of the statement 20 | // The starting line and column aren't always the absolute beginning of the statement just what's most 21 | // convenient. 22 | func (node ClassFieldAccessExpressionNode) Span() print.TextSpan { 23 | return node.Base.Span().SpanBetween(node.FieldIdentifier.Span) 24 | } 25 | 26 | // node print function 27 | func (node ClassFieldAccessExpressionNode) Print(indent string) { 28 | print.PrintC(print.Yellow, indent+"└ ClassFieldAccessExpressionNode") 29 | fmt.Println(indent + " └ Base: ") 30 | node.Base.Print(indent + " ") 31 | fmt.Printf("%s └ FieldIdentifier: %s\n", indent, node.FieldIdentifier.Value) 32 | } 33 | 34 | // "constructor" / ooga booga OOP cave man brain 35 | func CreateClassFieldAccessExpressionNode(base ExpressionNode, fieldId lexer.Token) ClassFieldAccessExpressionNode { 36 | return ClassFieldAccessExpressionNode{ 37 | Base: base, 38 | FieldIdentifier: fieldId, 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /nodes/expr-classFieldAssignmentEpxression.go: -------------------------------------------------------------------------------- 1 | package nodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/lexer" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | ) 8 | 9 | type ClassFieldAssignmentExpressionNode struct { 10 | ExpressionNode 11 | 12 | Base ExpressionNode 13 | FieldIdentifier lexer.Token 14 | Value ExpressionNode 15 | } 16 | 17 | // implement node type from interface 18 | func (ClassFieldAssignmentExpressionNode) NodeType() NodeType { return ClassFieldAssignmentExpression } 19 | 20 | // Position returns the starting line and column, and the total length of the statement 21 | // The starting line and column aren't always the absolute beginning of the statement just what's most 22 | // convenient. 23 | func (node ClassFieldAssignmentExpressionNode) Span() print.TextSpan { 24 | return node.Base.Span().SpanBetween(node.Value.Span()) 25 | } 26 | 27 | // node print function 28 | func (node ClassFieldAssignmentExpressionNode) Print(indent string) { 29 | print.PrintC(print.Yellow, indent+"└ ClassFieldAssignmentExpressionNode") 30 | fmt.Println(indent + " └ Base: ") 31 | node.Base.Print(indent + " ") 32 | fmt.Printf("%s └ FieldIdentifier: %s\n", indent, node.FieldIdentifier.Value) 33 | fmt.Println(indent + " └ Value: ") 34 | node.Value.Print(indent + " ") 35 | } 36 | 37 | // "constructor" / ooga booga OOP cave man brain 38 | func CreateClassFieldAssignmentExpressionNode(base ExpressionNode, fieldId lexer.Token, value ExpressionNode) ClassFieldAssignmentExpressionNode { 39 | return ClassFieldAssignmentExpressionNode{ 40 | Base: base, 41 | FieldIdentifier: fieldId, 42 | Value: value, 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /nodes/expr-dereferenceExpression.go: -------------------------------------------------------------------------------- 1 | package nodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/lexer" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | ) 8 | 9 | type DereferenceExpressionNode struct { 10 | ExpressionNode 11 | 12 | DerefKeyword lexer.Token 13 | Expression ExpressionNode 14 | } 15 | 16 | // implement node type from interface 17 | func (DereferenceExpressionNode) NodeType() NodeType { return DereferenceExpression } 18 | 19 | func (node DereferenceExpressionNode) Span() print.TextSpan { 20 | return node.DerefKeyword.Span.SpanBetween(node.Expression.Span()) 21 | } 22 | 23 | // node print function 24 | func (node DereferenceExpressionNode) Print(indent string) { 25 | print.PrintC(print.Yellow, indent+"└ DereferenceExpressionNode") 26 | fmt.Println(indent + " └ Expression: ") 27 | node.Expression.Print(indent + " ") 28 | } 29 | 30 | // "constructor" / ooga booga OOP cave man brain 31 | func CreateDereferenceExpressionNode(kw lexer.Token, expr ExpressionNode) DereferenceExpressionNode { 32 | return DereferenceExpressionNode{ 33 | DerefKeyword: kw, 34 | Expression: expr, 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /nodes/expr-lambdaExpression.go: -------------------------------------------------------------------------------- 1 | package nodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/lexer" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | ) 8 | 9 | // basic global statement member 10 | type LambdaExpressionNode struct { 11 | ExpressionNode 12 | 13 | LambdaKeyword lexer.Token 14 | Parameters []ParameterNode 15 | TypeClause TypeClauseNode 16 | Body BlockStatementNode 17 | } 18 | 19 | // implement node type from interface 20 | func (LambdaExpressionNode) NodeType() NodeType { return LambdaExpression } 21 | 22 | func (node LambdaExpressionNode) Span() print.TextSpan { 23 | span := node.LambdaKeyword.Span.SpanBetween(node.Body.Span()) 24 | return span 25 | } 26 | 27 | // node print function 28 | func (node LambdaExpressionNode) Print(indent string) { 29 | print.PrintC(print.Cyan, indent+"- LambdaExpressionNode") 30 | 31 | fmt.Println(indent + " └ Parameters: ") 32 | for _, param := range node.Parameters { 33 | param.Print(indent + " ") 34 | } 35 | 36 | if !node.TypeClause.ClauseIsSet { 37 | fmt.Printf("%s └ TypeClause: none\n", indent) 38 | } else { 39 | fmt.Println(indent + " └ TypeClause: ") 40 | node.TypeClause.Print(indent + " ") 41 | } 42 | 43 | fmt.Println(indent + " └ Body: ") 44 | node.Body.Print(indent + " ") 45 | } 46 | 47 | // "constructor" / ooga booga OOP cave man brain 48 | func CreateLambdaExpressionNode(kw lexer.Token, params []ParameterNode, typeClause TypeClauseNode, body BlockStatementNode) LambdaExpressionNode { 49 | return LambdaExpressionNode{ 50 | LambdaKeyword: kw, 51 | Parameters: params, 52 | TypeClause: typeClause, 53 | Body: body, 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /nodes/expr-literalExpression.go: -------------------------------------------------------------------------------- 1 | package nodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/lexer" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | ) 8 | 9 | // basic global statement member 10 | type LiteralExpressionNode struct { 11 | ExpressionNode 12 | 13 | LiteralToken lexer.Token 14 | LiteralValue interface{} 15 | IsNative bool 16 | } 17 | 18 | // implement node type from interface 19 | func (LiteralExpressionNode) NodeType() NodeType { return LiteralExpression } 20 | 21 | // Position returns the starting line and column, and the total length of the statement 22 | // The starting line and column aren't always the absolute beginning of the statement just what's most 23 | // convenient. 24 | func (node LiteralExpressionNode) Span() print.TextSpan { 25 | return node.LiteralToken.Span 26 | } 27 | 28 | // node print function 29 | func (node LiteralExpressionNode) Print(indent string) { 30 | print.PrintC(print.Yellow, indent+"└ LiteralExpressionNode") 31 | fmt.Printf("%s └ Value: %s\n", indent, node.LiteralToken.Value) 32 | } 33 | 34 | // "constructor" / ooga booga OOP cave man brain 35 | func CreateLiteralExpressionNode(tok lexer.Token) LiteralExpressionNode { 36 | return LiteralExpressionNode{ 37 | LiteralToken: tok, 38 | LiteralValue: tok.RealValue, 39 | IsNative: false, 40 | } 41 | } 42 | 43 | func CreateNativeLiteralExpressionNode(tok lexer.Token) LiteralExpressionNode { 44 | return LiteralExpressionNode{ 45 | LiteralToken: tok, 46 | LiteralValue: tok.RealValue, 47 | IsNative: true, 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /nodes/expr-makeArrayExpression.go: -------------------------------------------------------------------------------- 1 | package nodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/lexer" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | ) 8 | 9 | type MakeArrayExpressionNode struct { 10 | ExpressionNode 11 | 12 | IsLiteral bool 13 | 14 | MakeKeyword lexer.Token 15 | ClosingToken lexer.Token 16 | 17 | Type TypeClauseNode 18 | Length ExpressionNode 19 | LiteralValues []ExpressionNode 20 | } 21 | 22 | // implement node type from interface 23 | func (MakeArrayExpressionNode) NodeType() NodeType { return MakeArrayExpression } 24 | 25 | // Position returns the starting line and column, and the total length of the statement 26 | // The starting line and column aren't always the absolute beginning of the statement just what's most 27 | // convenient. 28 | func (node MakeArrayExpressionNode) Span() print.TextSpan { 29 | return node.MakeKeyword.Span.SpanBetween(node.ClosingToken.Span) 30 | } 31 | 32 | // node print function 33 | func (node MakeArrayExpressionNode) Print(indent string) { 34 | print.PrintC(print.Yellow, indent+"└ MakeArrayExpressionNode") 35 | fmt.Println(indent + " └ Type: ") 36 | node.Type.Print(indent + " ") 37 | } 38 | 39 | // "constructor" / ooga booga OOP cave man brain 40 | func CreateMakeArrayExpressionNode(typ TypeClauseNode, length ExpressionNode, makeKw lexer.Token, closing lexer.Token) MakeArrayExpressionNode { 41 | return MakeArrayExpressionNode{ 42 | Type: typ, 43 | Length: length, 44 | IsLiteral: false, 45 | MakeKeyword: makeKw, 46 | ClosingToken: closing, 47 | } 48 | } 49 | func CreateMakeArrayExpressionNodeLiteral(typ TypeClauseNode, literals []ExpressionNode, makeKw lexer.Token, closing lexer.Token) MakeArrayExpressionNode { 50 | return MakeArrayExpressionNode{ 51 | Type: typ, 52 | LiteralValues: literals, 53 | IsLiteral: true, 54 | MakeKeyword: makeKw, 55 | ClosingToken: closing, 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /nodes/expr-makeExpression.go: -------------------------------------------------------------------------------- 1 | package nodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/lexer" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | ) 8 | 9 | type MakeExpressionNode struct { 10 | ExpressionNode 11 | 12 | MakeKeyword lexer.Token 13 | ClosingToken lexer.Token 14 | 15 | Package *lexer.Token 16 | BaseType lexer.Token 17 | Arguments []ExpressionNode 18 | } 19 | 20 | // implement node type from interface 21 | func (MakeExpressionNode) NodeType() NodeType { return MakeExpression } 22 | 23 | // Position returns the starting line and column, and the total length of the statement 24 | // The starting line and column aren't always the absolute beginning of the statement just what's most 25 | // convenient. 26 | func (node MakeExpressionNode) Span() print.TextSpan { 27 | return node.MakeKeyword.Span.SpanBetween(node.ClosingToken.Span) 28 | } 29 | 30 | // node print function 31 | func (node MakeExpressionNode) Print(indent string) { 32 | print.PrintC(print.Yellow, indent+"└ MakeExpressionNode") 33 | fmt.Println(indent + " └ Type: " + node.BaseType.Value) 34 | fmt.Println(indent + " └ Arguments: ") 35 | for _, v := range node.Arguments { 36 | v.Print(indent + " ") 37 | } 38 | } 39 | 40 | // "constructor" / ooga booga OOP cave man brain 41 | func CreateMakeExpressionNode(pack *lexer.Token, typ lexer.Token, args []ExpressionNode, makeKw lexer.Token, closing lexer.Token) MakeExpressionNode { 42 | return MakeExpressionNode{ 43 | Package: pack, 44 | BaseType: typ, 45 | Arguments: args, 46 | MakeKeyword: makeKw, 47 | ClosingToken: closing, 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /nodes/expr-makeStructExpression.go: -------------------------------------------------------------------------------- 1 | package nodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/lexer" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | ) 8 | 9 | type MakeStructExpressionNode struct { 10 | ExpressionNode 11 | 12 | MakeKeyword lexer.Token 13 | ClosingToken lexer.Token 14 | 15 | Type lexer.Token 16 | LiteralValues []ExpressionNode 17 | } 18 | 19 | // implement node type from interface 20 | func (MakeStructExpressionNode) NodeType() NodeType { return MakeStructExpression } 21 | 22 | // Position returns the starting line and column, and the total length of the statement 23 | // The starting line and column aren't always the absolute beginning of the statement just what's most 24 | // convenient. 25 | func (node MakeStructExpressionNode) Span() print.TextSpan { 26 | return node.MakeKeyword.Span.SpanBetween(node.ClosingToken.Span) 27 | } 28 | 29 | // node print function 30 | func (node MakeStructExpressionNode) Print(indent string) { 31 | print.PrintC(print.Yellow, indent+"└ MakeStructExpressionNode") 32 | fmt.Println(indent + " └ Type: " + node.Type.Value) 33 | } 34 | 35 | // "constructor" / ooga booga OOP cave man brain 36 | func CreateMakeStructExpressionNode(typ lexer.Token, literals []ExpressionNode, makeKw lexer.Token, closing lexer.Token) MakeStructExpressionNode { 37 | return MakeStructExpressionNode{ 38 | Type: typ, 39 | LiteralValues: literals, 40 | MakeKeyword: makeKw, 41 | ClosingToken: closing, 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /nodes/expr-nameExpression.go: -------------------------------------------------------------------------------- 1 | package nodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/lexer" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | ) 8 | 9 | // aaaaaa, b even 10 | type NameExpressionNode struct { 11 | ExpressionNode 12 | 13 | InMain bool 14 | Identifier lexer.Token 15 | } 16 | 17 | // implement node type from interface 18 | func (NameExpressionNode) NodeType() NodeType { return NameExpression } 19 | 20 | // Position returns the starting line and column, and the total length of the statement 21 | // The starting line and column aren't always the absolute beginning of the statement just what's most 22 | // convenient. 23 | func (node NameExpressionNode) Span() print.TextSpan { 24 | return node.Identifier.Span 25 | } 26 | 27 | // node print function 28 | func (node NameExpressionNode) Print(indent string) { 29 | print.PrintC(print.Yellow, indent+"└ NameExpressionNode") 30 | fmt.Printf("%s └ Identifier: %s\n", indent, node.Identifier.Value) 31 | } 32 | 33 | // "constructor" / ooga booga OOP cave man brain 34 | func CreateNameExpressionNode(id lexer.Token) NameExpressionNode { 35 | return NameExpressionNode{ 36 | Identifier: id, 37 | } 38 | } 39 | 40 | func CreateMainNameExpressionNode(id lexer.Token) NameExpressionNode { 41 | return NameExpressionNode{ 42 | Identifier: id, 43 | InMain: true, 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /nodes/expr-packageCallExpression.go: -------------------------------------------------------------------------------- 1 | package nodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/lexer" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | ) 8 | 9 | type PackageCallExpressionNode struct { 10 | ExpressionNode 11 | 12 | Package lexer.Token 13 | Identifier lexer.Token 14 | Arguments []ExpressionNode 15 | 16 | ClosingToken lexer.Token 17 | } 18 | 19 | // implement node type from interface 20 | func (PackageCallExpressionNode) NodeType() NodeType { return PackageCallExpression } 21 | 22 | func (node PackageCallExpressionNode) Span() print.TextSpan { 23 | return node.Package.Span.SpanBetween(node.ClosingToken.Span) 24 | } 25 | 26 | // node print function 27 | func (node PackageCallExpressionNode) Print(indent string) { 28 | print.PrintC(print.Yellow, indent+"└ PackageCallExpressionNode") 29 | fmt.Printf("%s └ Package: %s\n", indent, node.Identifier.Value) 30 | fmt.Printf("%s └ Identifier: %s\n", indent, node.Identifier.Value) 31 | 32 | fmt.Println(indent + " └ Arguments: ") 33 | for _, arg := range node.Arguments { 34 | arg.Print(indent + " ") 35 | } 36 | } 37 | 38 | // "constructor" / ooga booga OOP cave man brain 39 | func CreatePackageCallExpressionNode(pck lexer.Token, id lexer.Token, args []ExpressionNode, closing lexer.Token) PackageCallExpressionNode { 40 | return PackageCallExpressionNode{ 41 | Package: pck, 42 | Identifier: id, 43 | Arguments: args, 44 | ClosingToken: closing, 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /nodes/expr-parenthesizedExpression.go: -------------------------------------------------------------------------------- 1 | package nodes 2 | 3 | import ( 4 | "github.com/ReCT-Lang/ReCT-Go-Compiler/lexer" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 6 | ) 7 | 8 | // aaaaaa 9 | type ParenthesisedExpressionNode struct { 10 | ExpressionNode 11 | 12 | OpenParenthesis lexer.Token 13 | Expression ExpressionNode 14 | ClosedParenthesis lexer.Token 15 | } 16 | 17 | // implement node type from interface 18 | func (ParenthesisedExpressionNode) NodeType() NodeType { return ParenthesisedExpression } 19 | 20 | // Position returns the starting line and column, and the total length of the statement 21 | // The starting line and column aren't always the absolute beginning of the statement just what's most 22 | // convenient. 23 | func (node ParenthesisedExpressionNode) Span() print.TextSpan { 24 | return node.OpenParenthesis.Span.SpanBetween(node.ClosedParenthesis.Span) 25 | } 26 | 27 | // node print function 28 | func (node ParenthesisedExpressionNode) Print(indent string) { 29 | print.PrintC(print.Yellow, indent+"└ ParenthesisedExpressionNode") 30 | node.Expression.Print(indent + " ") 31 | } 32 | 33 | // "constructor" / ooga booga OOP cave man brain 34 | func CreateParenthesisedExpressionNode(expression ExpressionNode, open lexer.Token, closed lexer.Token) ParenthesisedExpressionNode { 35 | return ParenthesisedExpressionNode{ 36 | Expression: expression, 37 | OpenParenthesis: open, 38 | ClosedParenthesis: closed, 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /nodes/expr-referenceExpression.go: -------------------------------------------------------------------------------- 1 | package nodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/lexer" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | ) 8 | 9 | type ReferenceExpressionNode struct { 10 | ExpressionNode 11 | 12 | RefKeyword lexer.Token 13 | Expression NameExpressionNode 14 | } 15 | 16 | // implement node type from interface 17 | func (ReferenceExpressionNode) NodeType() NodeType { return ReferenceExpression } 18 | 19 | func (node ReferenceExpressionNode) Span() print.TextSpan { 20 | return node.RefKeyword.Span.SpanBetween(node.Expression.Span()) 21 | } 22 | 23 | // node print function 24 | func (node ReferenceExpressionNode) Print(indent string) { 25 | print.PrintC(print.Yellow, indent+"└ ReferenceExpressionNode") 26 | fmt.Println(indent + " └ Expression: ") 27 | node.Expression.Print(indent + " ") 28 | } 29 | 30 | // "constructor" / ooga booga OOP cave man brain 31 | func CreateReferenceExpressionNode(kw lexer.Token, expr NameExpressionNode) ReferenceExpressionNode { 32 | return ReferenceExpressionNode{ 33 | RefKeyword: kw, 34 | Expression: expr, 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /nodes/expr-ternaryExpression.go: -------------------------------------------------------------------------------- 1 | package nodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 6 | ) 7 | 8 | type TernaryExpressionNode struct { 9 | ExpressionNode 10 | 11 | Condition ExpressionNode 12 | If ExpressionNode 13 | Else ExpressionNode 14 | } 15 | 16 | // implement node type from interface 17 | func (TernaryExpressionNode) NodeType() NodeType { return TernaryExpression } 18 | 19 | // Position returns the starting line and column, and the total length of the statement 20 | // The starting line and column aren't always the absolute beginning of the statement just what's most 21 | // convenient. 22 | func (node TernaryExpressionNode) Span() print.TextSpan { 23 | return node.Condition.Span().SpanBetween(node.Else.Span()) 24 | } 25 | 26 | // node print function 27 | func (node TernaryExpressionNode) Print(indent string) { 28 | print.PrintC(print.Yellow, indent+"└ TernaryExpressionNode") 29 | fmt.Println(indent + " └ Condition: ") 30 | node.Condition.Print(indent + " ") 31 | fmt.Println(indent + " └ If: ") 32 | node.If.Print(indent + " ") 33 | fmt.Println(indent + " └ Else: ") 34 | node.Else.Print(indent + " ") 35 | } 36 | 37 | // "constructor" / ooga booga OOP cave man brain 38 | func CreateTernaryExpressionNode(condition ExpressionNode, ifexpr ExpressionNode, elseexpr ExpressionNode) TernaryExpressionNode { 39 | return TernaryExpressionNode{ 40 | Condition: condition, 41 | If: ifexpr, 42 | Else: elseexpr, 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /nodes/expr-thisExpression.go: -------------------------------------------------------------------------------- 1 | package nodes 2 | 3 | import ( 4 | "github.com/ReCT-Lang/ReCT-Go-Compiler/lexer" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 6 | ) 7 | 8 | type ThisExpressionNode struct { 9 | ExpressionNode 10 | 11 | ThisKeyword lexer.Token 12 | } 13 | 14 | // implement node type from interface 15 | func (ThisExpressionNode) NodeType() NodeType { return ThisExpression } 16 | 17 | func (node ThisExpressionNode) Span() print.TextSpan { 18 | return node.ThisKeyword.Span 19 | } 20 | 21 | // node print function 22 | func (node ThisExpressionNode) Print(indent string) { 23 | print.PrintC(print.Yellow, indent+"└ ThisExpressionNode") 24 | } 25 | 26 | // "constructor" / ooga booga OOP cave man brain 27 | func CreateThisExpressionNode(kw lexer.Token) ThisExpressionNode { 28 | return ThisExpressionNode{ 29 | ThisKeyword: kw, 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /nodes/expr-typeCallEpxression.go: -------------------------------------------------------------------------------- 1 | package nodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/lexer" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | ) 8 | 9 | type TypeCallExpressionNode struct { 10 | ExpressionNode 11 | 12 | Base ExpressionNode 13 | CallIdentifier lexer.Token 14 | Arguments []ExpressionNode 15 | ClosingToken lexer.Token 16 | } 17 | 18 | // implement node type from interface 19 | func (TypeCallExpressionNode) NodeType() NodeType { return TypeCallExpression } 20 | 21 | // Position returns the starting line and column, and the total length of the statement 22 | // The starting line and column aren't always the absolute beginning of the statement just what's most 23 | // convenient. 24 | func (node TypeCallExpressionNode) Span() print.TextSpan { 25 | return node.Base.Span().SpanBetween(node.ClosingToken.Span) 26 | } 27 | 28 | // node print function 29 | func (node TypeCallExpressionNode) Print(indent string) { 30 | print.PrintC(print.Yellow, indent+"└ TypeCallExpressionNode") 31 | fmt.Println(indent + " └ Base: ") 32 | node.Base.Print(indent + " ") 33 | fmt.Printf("%s └ CallIdentifier: %s\n", indent, node.CallIdentifier.Value) 34 | fmt.Println(indent + " └ Arguments: ") 35 | for _, arg := range node.Arguments { 36 | arg.Print(indent + " ") 37 | } 38 | } 39 | 40 | // "constructor" / ooga booga OOP cave man brain 41 | func CreateTypeCallExpressionNode(base ExpressionNode, callId lexer.Token, args []ExpressionNode, closing lexer.Token) TypeCallExpressionNode { 42 | return TypeCallExpressionNode{ 43 | Base: base, 44 | CallIdentifier: callId, 45 | Arguments: args, 46 | ClosingToken: closing, 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /nodes/expr-unaryExpression.go: -------------------------------------------------------------------------------- 1 | package nodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/lexer" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | ) 8 | 9 | type UnaryExpressionNode struct { 10 | ExpressionNode 11 | 12 | Operator lexer.Token 13 | Operand ExpressionNode 14 | } 15 | 16 | // implement node type from interface 17 | func (UnaryExpressionNode) NodeType() NodeType { return UnaryExpression } 18 | 19 | // Position returns the starting line and column, and the total length of the statement 20 | // The starting line and column aren't always the absolute beginning of the statement just what's most 21 | // convenient. 22 | func (node UnaryExpressionNode) Span() print.TextSpan { 23 | return node.Operator.Span.SpanBetween(node.Operand.Span()) 24 | } 25 | 26 | // node print function 27 | func (node UnaryExpressionNode) Print(indent string) { 28 | print.PrintC(print.Yellow, indent+"└ UnaryExpressionNode") 29 | fmt.Printf("%s └ Operator: %s\n", indent, node.Operator.Kind) 30 | fmt.Println(indent + " └ Operand: ") 31 | node.Operand.Print(indent + " ") 32 | } 33 | 34 | // "constructor" / ooga booga OOP cave man brain 35 | func CreateUnaryExpressionNode(op lexer.Token, expr ExpressionNode) UnaryExpressionNode { 36 | return UnaryExpressionNode{ 37 | Operator: op, 38 | Operand: expr, 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /nodes/expr-variableEditorExpression.go: -------------------------------------------------------------------------------- 1 | package nodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/lexer" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | ) 8 | 9 | type VariableEditorExpressionNode struct { 10 | ExpressionNode 11 | 12 | Identifier lexer.Token 13 | Operator lexer.Token 14 | Expression ExpressionNode 15 | IsSingleStep bool // things like ++ or -- 16 | } 17 | 18 | // implement node type from interface 19 | func (VariableEditorExpressionNode) NodeType() NodeType { return VariableEditorExpression } 20 | 21 | // Position returns the starting line and column, and the total length of the statement 22 | // The starting line and column aren't always the absolute beginning of the statement just what's most 23 | // convenient. 24 | func (node VariableEditorExpressionNode) Span() print.TextSpan { 25 | span := node.Identifier.Span.SpanBetween(node.Operator.Span) 26 | if !node.IsSingleStep { 27 | span.SpanBetween(node.Expression.Span()) 28 | } 29 | 30 | return span 31 | } 32 | 33 | // node print function 34 | func (node VariableEditorExpressionNode) Print(indent string) { 35 | print.PrintC(print.Yellow, indent+"└ VariableEditorExpressionNode") 36 | fmt.Printf("%s └ Identifier: %s\n", indent, node.Identifier.Value) 37 | fmt.Printf("%s └ Operator: %s\n", indent, node.Operator.Kind) 38 | fmt.Printf("%s └ IsSingleStep: %t\n", indent, node.IsSingleStep) 39 | 40 | if node.Expression != nil { 41 | fmt.Println(indent + " └ Expression: ") 42 | node.Expression.Print(indent + " ") 43 | } 44 | } 45 | 46 | // "constructor" / ooga booga OOP cave man brain 47 | func CreateVariableEditorExpressionNode(id lexer.Token, op lexer.Token, expr ExpressionNode, singleStep bool) VariableEditorExpressionNode { 48 | return VariableEditorExpressionNode{ 49 | Identifier: id, 50 | Operator: op, 51 | Expression: expr, 52 | IsSingleStep: singleStep, 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /nodes/node-classDeclarationMember.go: -------------------------------------------------------------------------------- 1 | package nodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/lexer" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | ) 8 | 9 | type ClassDeclarationMember struct { 10 | MemberNode 11 | 12 | ClassKeyword lexer.Token 13 | Identifier lexer.Token 14 | Members []MemberNode 15 | ClosingToken lexer.Token 16 | } 17 | 18 | // implement node type from interface 19 | func (ClassDeclarationMember) NodeType() NodeType { return ClassDeclaration } 20 | 21 | func (node ClassDeclarationMember) Span() print.TextSpan { 22 | return node.ClassKeyword.Span.SpanBetween(node.ClosingToken.Span) 23 | } 24 | 25 | // node print function 26 | func (node ClassDeclarationMember) Print(indent string) { 27 | print.PrintC(print.Cyan, indent+"- ClassDeclarationMember") 28 | fmt.Printf("%s └ Identifier: %s\n", indent, node.Identifier.Kind) 29 | 30 | fmt.Println(indent + " └ Members: ") 31 | for _, mem := range node.Members { 32 | mem.Print(indent + " ") 33 | } 34 | } 35 | 36 | // "constructor" / ooga booga OOP cave man brain 37 | func CreateClassDeclarationMember(kw lexer.Token, id lexer.Token, members []MemberNode, closing lexer.Token) ClassDeclarationMember { 38 | return ClassDeclarationMember{ 39 | ClassKeyword: kw, 40 | Identifier: id, 41 | Members: members, 42 | ClosingToken: closing, 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /nodes/node-enumDeclarationMember.go: -------------------------------------------------------------------------------- 1 | package nodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/lexer" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | ) 8 | 9 | type EnumDeclarationMember struct { 10 | MemberNode 11 | 12 | StructKeyword lexer.Token 13 | Identifier lexer.Token 14 | Fields map[lexer.Token]*LiteralExpressionNode 15 | ClosingToken lexer.Token 16 | } 17 | 18 | // implement node type from interface 19 | func (EnumDeclarationMember) NodeType() NodeType { return EnumDeclaration } 20 | 21 | func (node EnumDeclarationMember) Span() print.TextSpan { 22 | return node.StructKeyword.Span.SpanBetween(node.ClosingToken.Span) 23 | } 24 | 25 | // node print function 26 | func (node EnumDeclarationMember) Print(indent string) { 27 | print.PrintC(print.Cyan, indent+"- EnumDeclarationMember") 28 | fmt.Printf("%s └ Identifier: %s\n", indent, node.Identifier.Kind) 29 | } 30 | 31 | // "constructor" / ooga booga OOP cave man brain 32 | func CreateEnumDeclarationMember(kw lexer.Token, id lexer.Token, fields map[lexer.Token]*LiteralExpressionNode, closing lexer.Token) EnumDeclarationMember { 33 | return EnumDeclarationMember{ 34 | StructKeyword: kw, 35 | Identifier: id, 36 | Fields: fields, 37 | ClosingToken: closing, 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /nodes/node-externalFunctionDeclarationMember.go: -------------------------------------------------------------------------------- 1 | package nodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/lexer" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | ) 8 | 9 | // basic global statement member 10 | type ExternalFunctionDeclarationMember struct { 11 | MemberNode 12 | 13 | ExternalKeyword lexer.Token 14 | Identifier lexer.Token 15 | Parameters []ParameterNode 16 | ClosingToken lexer.Token 17 | TypeClause TypeClauseNode 18 | IsVariadic bool 19 | IsAdapted bool 20 | } 21 | 22 | // implement node type from interface 23 | func (ExternalFunctionDeclarationMember) NodeType() NodeType { return ExternalFunctionDeclaration } 24 | 25 | func (node ExternalFunctionDeclarationMember) Span() print.TextSpan { 26 | span := node.ExternalKeyword.Span.SpanBetween(node.ClosingToken.Span) 27 | if node.TypeClause.ClauseIsSet { 28 | span = span.SpanBetween(node.TypeClause.Span()) 29 | } 30 | 31 | return span 32 | } 33 | 34 | // node print function 35 | func (node ExternalFunctionDeclarationMember) Print(indent string) { 36 | print.PrintC(print.Cyan, indent+"- FunctionDeclarationMember") 37 | fmt.Printf("%s └ Identifier: %s\n", indent, node.Identifier.Kind) 38 | fmt.Printf("%s └ IsVariadic: %t\n", indent, node.IsVariadic) 39 | fmt.Printf("%s └ IsAdapted: %t\n", indent, node.IsAdapted) 40 | 41 | fmt.Println(indent + " └ Parameters: ") 42 | for _, param := range node.Parameters { 43 | param.Print(indent + " ") 44 | } 45 | 46 | if !node.TypeClause.ClauseIsSet { 47 | fmt.Printf("%s └ TypeClause: none\n", indent) 48 | } else { 49 | fmt.Println(indent + " └ TypeClause: ") 50 | node.TypeClause.Print(indent + " ") 51 | } 52 | } 53 | 54 | // "constructor" / ooga booga OOP cave man brain 55 | func CreateExternalFunctionDeclarationMember(kw lexer.Token, id lexer.Token, params []ParameterNode, typeClause TypeClauseNode, closing lexer.Token, variadic bool, adapted bool) ExternalFunctionDeclarationMember { 56 | return ExternalFunctionDeclarationMember{ 57 | ExternalKeyword: kw, 58 | Identifier: id, 59 | Parameters: params, 60 | TypeClause: typeClause, 61 | ClosingToken: closing, 62 | IsVariadic: variadic, 63 | IsAdapted: adapted, 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /nodes/node-functionDeclarationMember.go: -------------------------------------------------------------------------------- 1 | package nodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/lexer" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | ) 8 | 9 | // basic global statement member 10 | type FunctionDeclarationMember struct { 11 | MemberNode 12 | 13 | FunctionKeyword lexer.Token 14 | Identifier lexer.Token 15 | Parameters []ParameterNode 16 | TypeClause TypeClauseNode 17 | Body BlockStatementNode 18 | IsPublic bool 19 | } 20 | 21 | // implement node type from interface 22 | func (FunctionDeclarationMember) NodeType() NodeType { return FunctionDeclaration } 23 | 24 | // Position returns the starting line and column, and the total length of the statement 25 | // The starting line and column aren't always the absolute beginning of the statement just what's most 26 | // convenient. 27 | // For FunctionDeclarationMember we don't get the length of the body, only the keyword, name, parameters, and type 28 | func (node FunctionDeclarationMember) Span() print.TextSpan { 29 | span := node.FunctionKeyword.Span 30 | 31 | if node.FunctionKeyword.Kind == lexer.FunctionKeyword { 32 | span = span.SpanBetween(node.Body.Span()) 33 | } else { 34 | span = span.SpanBetween(node.Identifier.Span) 35 | } 36 | 37 | return span 38 | } 39 | 40 | // node print function 41 | func (node FunctionDeclarationMember) Print(indent string) { 42 | print.PrintC(print.Cyan, indent+"- FunctionDeclarationMember") 43 | fmt.Printf("%s └ Identifier: %s\n", indent, node.Identifier.Kind) 44 | fmt.Printf("%s └ IsPublic: %t\n", indent, node.IsPublic) 45 | 46 | fmt.Println(indent + " └ Parameters: ") 47 | for _, param := range node.Parameters { 48 | param.Print(indent + " ") 49 | } 50 | 51 | if !node.TypeClause.ClauseIsSet { 52 | fmt.Printf("%s └ TypeClause: none\n", indent) 53 | } else { 54 | fmt.Println(indent + " └ TypeClause: ") 55 | node.TypeClause.Print(indent + " ") 56 | } 57 | 58 | fmt.Println(indent + " └ Body: ") 59 | node.Body.Print(indent + " ") 60 | } 61 | 62 | // "constructor" / ooga booga OOP cave man brain 63 | func CreateFunctionDeclarationMember(kw lexer.Token, id lexer.Token, params []ParameterNode, typeClause TypeClauseNode, body BlockStatementNode, public bool) FunctionDeclarationMember { 64 | return FunctionDeclarationMember{ 65 | FunctionKeyword: kw, 66 | Identifier: id, 67 | Parameters: params, 68 | TypeClause: typeClause, 69 | Body: body, 70 | IsPublic: public, 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /nodes/node-globalStatementMember.go: -------------------------------------------------------------------------------- 1 | package nodes 2 | 3 | import ( 4 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 5 | ) 6 | 7 | // basic global statement member 8 | type GlobalStatementMember struct { 9 | MemberNode 10 | Statement StatementNode 11 | } 12 | 13 | // implement node type from interface 14 | func (GlobalStatementMember) NodeType() NodeType { return GlobalStatement } 15 | 16 | // Position returns the starting line and column, and the total length of the statement 17 | // The starting line and column aren't always the absolute beginning of the statement just what's most 18 | // convenient. 19 | func (node GlobalStatementMember) Span() print.TextSpan { 20 | return node.Statement.Span() 21 | } 22 | 23 | // node print function 24 | func (node GlobalStatementMember) Print(indent string) { 25 | print.PrintC(print.Cyan, indent+"- GlobalStatementMember") 26 | node.Statement.Print(indent + " ") 27 | } 28 | 29 | // "constructor" / ooga booga OOP cave man brain 30 | func CreateGlobalStatementMember(stmt StatementNode) GlobalStatementMember { 31 | return GlobalStatementMember{ 32 | Statement: stmt, 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /nodes/node-packageAliasMember.go: -------------------------------------------------------------------------------- 1 | package nodes 2 | 3 | import ( 4 | "github.com/ReCT-Lang/ReCT-Go-Compiler/lexer" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 6 | ) 7 | 8 | // basic global statement member 9 | type PackageAliasMember struct { 10 | MemberNode 11 | 12 | PackageKeyword lexer.Token 13 | Package lexer.Token 14 | Alias lexer.Token 15 | } 16 | 17 | // implement node type from interface 18 | func (PackageAliasMember) NodeType() NodeType { return PackageAlias } 19 | 20 | // Position returns the starting line and column, and the total length of the statement 21 | // The starting line and column aren't always the absolute beginning of the statement just what's most 22 | // convenient. 23 | func (node PackageAliasMember) Span() print.TextSpan { 24 | return node.PackageKeyword.Span.SpanBetween(node.Alias.Span) 25 | } 26 | 27 | // node print function 28 | func (node PackageAliasMember) Print(indent string) { 29 | print.PrintC(print.Cyan, indent+"- PackageAliasMember: "+node.Package.Value+" -> "+node.Alias.Value) 30 | } 31 | 32 | // "constructor" / ooga booga OOP cave man brain 33 | func CreatePackageAliasMember(kw lexer.Token, pkg lexer.Token, alias lexer.Token) PackageAliasMember { 34 | return PackageAliasMember{ 35 | PackageKeyword: kw, 36 | Package: pkg, 37 | Alias: alias, 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /nodes/node-packageReferenceMember.go: -------------------------------------------------------------------------------- 1 | package nodes 2 | 3 | import ( 4 | "github.com/ReCT-Lang/ReCT-Go-Compiler/lexer" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 6 | ) 7 | 8 | // basic global statement member 9 | type PackageReferenceMember struct { 10 | MemberNode 11 | 12 | PackageKeyword lexer.Token 13 | Package lexer.Token 14 | } 15 | 16 | // implement node type from interface 17 | func (PackageReferenceMember) NodeType() NodeType { return PackageReference } 18 | 19 | // Position returns the starting line and column, and the total length of the statement 20 | // The starting line and column aren't always the absolute beginning of the statement just what's most 21 | // convenient. 22 | func (node PackageReferenceMember) Span() print.TextSpan { 23 | return node.PackageKeyword.Span.SpanBetween(node.Package.Span) 24 | } 25 | 26 | // node print function 27 | func (node PackageReferenceMember) Print(indent string) { 28 | print.PrintC(print.Cyan, indent+"- PackageReferenceMember: "+node.Package.Value) 29 | } 30 | 31 | // "constructor" / ooga booga OOP cave man brain 32 | func CreatePackageReferenceMember(kw lexer.Token, pkg lexer.Token) PackageReferenceMember { 33 | return PackageReferenceMember{ 34 | PackageKeyword: kw, 35 | Package: pkg, 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /nodes/node-packageUseMember.go: -------------------------------------------------------------------------------- 1 | package nodes 2 | 3 | import ( 4 | "github.com/ReCT-Lang/ReCT-Go-Compiler/lexer" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 6 | ) 7 | 8 | // basic global statement member 9 | type PackageUseMember struct { 10 | MemberNode 11 | 12 | PackageKeyword lexer.Token 13 | Package lexer.Token 14 | } 15 | 16 | // implement node type from interface 17 | func (PackageUseMember) NodeType() NodeType { return PackageUse } 18 | 19 | // Position returns the starting line and column, and the total length of the statement 20 | // The starting line and column aren't always the absolute beginning of the statement just what's most 21 | // convenient. 22 | func (node PackageUseMember) Span() print.TextSpan { 23 | return node.PackageKeyword.Span.SpanBetween(node.Package.Span) 24 | } 25 | 26 | // node print function 27 | func (node PackageUseMember) Print(indent string) { 28 | print.PrintC(print.Cyan, indent+"- PackageUseMember: "+node.Package.Value) 29 | } 30 | 31 | // "constructor" / ooga booga OOP cave man brain 32 | func CreatePackageUseMember(kw lexer.Token, pkg lexer.Token) PackageUseMember { 33 | return PackageUseMember{ 34 | PackageKeyword: kw, 35 | Package: pkg, 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /nodes/node-parameterNode.go: -------------------------------------------------------------------------------- 1 | package nodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/lexer" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | ) 8 | 9 | // basic global statement member 10 | type ParameterNode struct { 11 | SyntaxNode 12 | 13 | Identifier lexer.Token 14 | TypeClause TypeClauseNode 15 | } 16 | 17 | // implement node type from interface 18 | func (ParameterNode) NodeType() NodeType { return Parameter } 19 | 20 | // Position returns the starting line and column, and the total length of the statement 21 | // The starting line and column aren't always the absolute beginning of the statement just what's most 22 | // convenient. 23 | func (node ParameterNode) Span() print.TextSpan { 24 | return node.Identifier.Span.SpanBetween(node.TypeClause.Span()) 25 | } 26 | 27 | // node print function 28 | func (node ParameterNode) Print(indent string) { 29 | print.PrintC(print.Green, indent+"└ ParameterNode") 30 | fmt.Printf("%s └ Identifier: %s\n", indent, node.Identifier.Value) 31 | 32 | if !node.TypeClause.ClauseIsSet { 33 | fmt.Printf("%s └ TypeClause: none\n", indent) 34 | } else { 35 | fmt.Println(indent + " └ TypeClause: ") 36 | node.TypeClause.Print(indent + " ") 37 | } 38 | 39 | } 40 | 41 | // "constructor" / ooga booga OOP cave man brain 42 | func CreateParameterNode(id lexer.Token, typeClause TypeClauseNode) ParameterNode { 43 | return ParameterNode{ 44 | Identifier: id, 45 | TypeClause: typeClause, 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /nodes/node-structDeclarationMember.go: -------------------------------------------------------------------------------- 1 | package nodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/lexer" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | ) 8 | 9 | type StructDeclarationMember struct { 10 | MemberNode 11 | 12 | StructKeyword lexer.Token 13 | Identifier lexer.Token 14 | Fields []ParameterNode 15 | ClosingToken lexer.Token 16 | } 17 | 18 | // implement node type from interface 19 | func (StructDeclarationMember) NodeType() NodeType { return StructDeclaration } 20 | 21 | func (node StructDeclarationMember) Span() print.TextSpan { 22 | return node.StructKeyword.Span.SpanBetween(node.ClosingToken.Span) 23 | } 24 | 25 | // node print function 26 | func (node StructDeclarationMember) Print(indent string) { 27 | print.PrintC(print.Cyan, indent+"- ClassDeclarationMember") 28 | fmt.Printf("%s └ Identifier: %s\n", indent, node.Identifier.Kind) 29 | } 30 | 31 | // "constructor" / ooga booga OOP cave man brain 32 | func CreateStructDeclarationMember(kw lexer.Token, id lexer.Token, fields []ParameterNode, closing lexer.Token) StructDeclarationMember { 33 | return StructDeclarationMember{ 34 | StructKeyword: kw, 35 | Identifier: id, 36 | Fields: fields, 37 | ClosingToken: closing, 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /nodes/stmt-blockStatement.go: -------------------------------------------------------------------------------- 1 | package nodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/lexer" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | ) 8 | 9 | // basic global statement member 10 | type BlockStatementNode struct { 11 | StatementNode 12 | 13 | OpenBrace lexer.Token 14 | Statements []StatementNode 15 | CloseBrace lexer.Token 16 | } 17 | 18 | // implement node type from interface 19 | func (BlockStatementNode) NodeType() NodeType { return BlockStatement } 20 | 21 | // Position returns the starting line and column, and the total length of the statement 22 | // The starting line and column aren't always the absolute beginning of the statement just what's most 23 | // convenient. 24 | // BlockStatementNode is a bit weird because it gets the length of all the statements... 25 | // Oh well, I'm sure nothing wacky can happen from this! - tokorv 26 | func (node BlockStatementNode) Span() print.TextSpan { 27 | return node.OpenBrace.Span.SpanBetween(node.CloseBrace.Span) 28 | } 29 | 30 | // node print function 31 | func (node BlockStatementNode) Print(indent string) { 32 | print.PrintC(print.Green, indent+"└ BlockStatementNode") 33 | fmt.Printf("%s └ OpenBrace: %s\n", indent, node.OpenBrace.Kind) 34 | fmt.Printf("%s └ CloseBrace: %s\n", indent, node.CloseBrace.Kind) 35 | fmt.Println(indent + " └ Statements: ") 36 | 37 | for _, stmt := range node.Statements { 38 | stmt.Print(indent + " ") 39 | } 40 | 41 | } 42 | 43 | // "constructor" / ooga booga OOP cave man brain 44 | func CreateBlockStatementNode(openBrace lexer.Token, statements []StatementNode, closeBrace lexer.Token) BlockStatementNode { 45 | return BlockStatementNode{ 46 | OpenBrace: openBrace, 47 | Statements: statements, 48 | CloseBrace: closeBrace, 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /nodes/stmt-breakStatement.go: -------------------------------------------------------------------------------- 1 | package nodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/lexer" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | ) 8 | 9 | // ReturnStatementNode like: return "Yo mama"; there, get rect. 10 | type BreakStatementNode struct { 11 | StatementNode 12 | 13 | Keyword lexer.Token 14 | } 15 | 16 | // NodeType Copy + Paste 17 | func (BreakStatementNode) NodeType() NodeType { return BreakStatement } 18 | 19 | // Position returns the starting line and column, and the total length of the statement 20 | // The starting line and column aren't always the absolute beginning of the statement just what's most 21 | // convenient. 22 | func (node BreakStatementNode) Span() print.TextSpan { 23 | return node.Keyword.Span 24 | } 25 | 26 | // Print Prints beautiful stuff in console 27 | func (node BreakStatementNode) Print(indent string) { 28 | print.PrintC(print.Green, indent+"└ BreakStatement") 29 | fmt.Printf("%s └ Keyword: %s\n", indent, node.Keyword.Kind) 30 | } 31 | 32 | // "constructor" / ooga booga OOP cave man brain - Same -_- 33 | func CreateBreakStatement(keyword lexer.Token) BreakStatementNode { 34 | return BreakStatementNode{ 35 | Keyword: keyword, 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /nodes/stmt-continueStatement.go: -------------------------------------------------------------------------------- 1 | package nodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/lexer" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | ) 8 | 9 | // ReturnStatementNode like: return "Yo mama"; there, get rect. 10 | type ContinueStatementNode struct { 11 | StatementNode 12 | 13 | Keyword lexer.Token 14 | } 15 | 16 | // NodeType Copy + Paste 17 | func (ContinueStatementNode) NodeType() NodeType { return ContinueStatement } 18 | 19 | // Position returns the starting line and column, and the total length of the statement 20 | // The starting line and column aren't always the absolute beginning of the statement just what's most 21 | // convenient. 22 | func (node ContinueStatementNode) Span() print.TextSpan { 23 | return node.Keyword.Span 24 | } 25 | 26 | // Print Prints beautiful stuff in console 27 | func (node ContinueStatementNode) Print(indent string) { 28 | print.PrintC(print.Green, indent+"└ ReturnStatementNode") 29 | fmt.Printf("%s └ Keyword: %s\n", indent, node.Keyword.Kind) 30 | } 31 | 32 | // "constructor" / ooga booga OOP cave man brain - Same -_- 33 | func CreateContinueStatement(keyword lexer.Token) ContinueStatementNode { 34 | return ContinueStatementNode{ 35 | Keyword: keyword, 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /nodes/stmt-expressionStatement.go: -------------------------------------------------------------------------------- 1 | package nodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 6 | ) 7 | 8 | // basic global statement member 9 | type ExpressionStatementNode struct { 10 | StatementNode 11 | 12 | Expression ExpressionNode 13 | } 14 | 15 | // implement node type from interface 16 | func (ExpressionStatementNode) NodeType() NodeType { return ExpressionStatement } 17 | 18 | // Position returns the starting line and column, and the total length of the statement 19 | // The starting line and column aren't always the absolute beginning of the statement just what's most 20 | // convenient. 21 | func (node ExpressionStatementNode) Span() print.TextSpan { 22 | return node.Expression.Span() 23 | } 24 | 25 | // node print function 26 | func (node ExpressionStatementNode) Print(indent string) { 27 | print.PrintC(print.Green, indent+"└ ExpressionStatementNode") 28 | fmt.Println(indent + " └ Expression: ") 29 | node.Expression.Print(indent + " ") 30 | 31 | } 32 | 33 | // "constructor" / ooga booga OOP cave man brain 34 | func CreateExpressionStatementNode(expr ExpressionNode) ExpressionStatementNode { 35 | return ExpressionStatementNode{ 36 | Expression: expr, 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /nodes/stmt-forStatement.go: -------------------------------------------------------------------------------- 1 | package nodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/lexer" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | ) 8 | 9 | // ForStatementNode for(var i = 0; i < 10; i++) Print("Hello"); 10 | type ForStatementNode struct { 11 | StatementNode 12 | 13 | Keyword lexer.Token 14 | Initaliser VariableDeclarationStatementNode 15 | Condition ExpressionNode 16 | Updation StatementNode 17 | Statement StatementNode 18 | } 19 | 20 | // NodeType Copy + Paste 21 | func (ForStatementNode) NodeType() NodeType { return ForStatement } 22 | 23 | // Position returns the starting line and column, and the total length of the statement 24 | // The starting line and column aren't always the absolute beginning of the statement just what's most 25 | // convenient. 26 | // ForStatementNode we don't do the Statement because it can be super long (i.e., a block statement) 27 | func (node ForStatementNode) Span() print.TextSpan { 28 | return node.Keyword.Span.SpanBetween(node.Statement.Span()) 29 | } 30 | 31 | // Print Prints beautiful stuff in console 32 | func (node ForStatementNode) Print(indent string) { 33 | print.PrintC(print.Green, indent+"└ ForStatementNode") 34 | fmt.Printf("%s └ Keyword: %s\n", indent, node.Keyword.Kind) 35 | fmt.Println(indent + " └ Initaliser: ") 36 | node.Initaliser.Print(indent + " ") 37 | fmt.Println(indent + " └ Condition: ") 38 | node.Condition.Print(indent + " ") 39 | fmt.Println(indent + " └ Updation: ") 40 | node.Updation.Print(indent + " ") 41 | fmt.Println(indent + " └ Statement: ") 42 | node.Statement.Print(indent + " ") 43 | } 44 | 45 | // "constructor" / ooga booga OOP cave man brain - Same -_- 46 | func CreateForStatementNode(keyword lexer.Token, initaliser VariableDeclarationStatementNode, condition ExpressionNode, updation ExpressionNode, statement StatementNode) ForStatementNode { 47 | return ForStatementNode{ 48 | Keyword: keyword, 49 | Initaliser: initaliser, 50 | Condition: condition, 51 | Updation: updation, 52 | Statement: statement, 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /nodes/stmt-fromToStatement.go: -------------------------------------------------------------------------------- 1 | package nodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/lexer" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | ) 8 | 9 | // FromToStatementNode joke comments get old after awhile 10 | type FromToStatementNode struct { 11 | StatementNode 12 | 13 | Keyword lexer.Token 14 | Identifier lexer.Token 15 | LowerBound ExpressionNode 16 | UpperBound ExpressionNode 17 | Statement StatementNode 18 | } 19 | 20 | // NodeType Copy + Paste again 21 | func (FromToStatementNode) NodeType() NodeType { return FromToStatement } 22 | 23 | // Position returns the starting line and column, and the total length of the statement 24 | // The starting line and column aren't always the absolute beginning of the statement just what's most 25 | // convenient. 26 | // FromToStatementNode we don't do the Statement because it can be super long (i.e., a block statement) 27 | func (node FromToStatementNode) Span() print.TextSpan { 28 | return node.Keyword.Span.SpanBetween(node.Statement.Span()) 29 | } 30 | 31 | // Print Prints beautiful stuff in console 32 | func (node FromToStatementNode) Print(indent string) { 33 | print.PrintC(print.Green, indent+"└ FromToStatementNode") 34 | fmt.Printf("%s └ Keyword: %s\n", indent, node.Keyword.Kind) 35 | fmt.Printf("%s └ Identifier: %s\n", indent, node.Identifier.Value) 36 | fmt.Println(indent + " └ Lower Bound: ") 37 | node.LowerBound.Print(indent + " ") 38 | fmt.Println(indent + " └ Upper Bound: ") 39 | node.UpperBound.Print(indent + " ") 40 | fmt.Println(indent + " └ Statement: ") 41 | node.Statement.Print(indent + " ") 42 | } 43 | 44 | // "constructor" / ooga booga OOP cave man brain - Same -_- 45 | func CreateFromToStatementNode(keyword lexer.Token, id lexer.Token, lower ExpressionNode, upper ExpressionNode, statement StatementNode) FromToStatementNode { 46 | return FromToStatementNode{ 47 | Keyword: keyword, 48 | Identifier: id, 49 | LowerBound: lower, 50 | UpperBound: upper, 51 | Statement: statement, 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /nodes/stmt-ifStatement.go: -------------------------------------------------------------------------------- 1 | package nodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/lexer" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | ) 8 | 9 | // basic global statement member 10 | type IfStatementNode struct { 11 | StatementNode 12 | 13 | IfKeyword lexer.Token 14 | Condition ExpressionNode 15 | ThenStatement StatementNode 16 | ElseClause ElseClauseNode 17 | } 18 | 19 | // implement node type from interface 20 | func (IfStatementNode) NodeType() NodeType { return IfStatement } 21 | 22 | // Position returns the starting line and column, and the total length of the statement 23 | // The starting line and column aren't always the absolute beginning of the statement just what's most 24 | // convenient. 25 | // IfStatementNode we don't do the Statement because it can be super long (i.e., a block statement) 26 | func (node IfStatementNode) Span() print.TextSpan { 27 | return node.IfKeyword.Span.SpanBetween(node.ThenStatement.Span()).SpanBetween(node.ElseClause.Span()) 28 | } 29 | 30 | // node print function 31 | func (node IfStatementNode) Print(indent string) { 32 | print.PrintC(print.Green, indent+"└ IfStatementNode") 33 | fmt.Printf("%s └ Keyword: %s\n", indent, node.IfKeyword.Kind) 34 | fmt.Println(indent + " └ Condition: ") 35 | node.Condition.Print(indent + " ") 36 | fmt.Println(indent + " └ Statement: ") 37 | node.ThenStatement.Print(indent + " ") 38 | 39 | if !node.ElseClause.ClauseIsSet { 40 | fmt.Printf("%s └ ElseClause: none\n", indent) 41 | } else { 42 | fmt.Println(indent + " └ ElseClause: ") 43 | node.ElseClause.Print(indent + " ") 44 | } 45 | 46 | } 47 | 48 | // "constructor" / ooga booga OOP cave man brain 49 | func CreateIfStatementNode(kw lexer.Token, cond ExpressionNode, then StatementNode, elseClause ElseClauseNode) IfStatementNode { 50 | return IfStatementNode{ 51 | IfKeyword: kw, 52 | Condition: cond, 53 | ThenStatement: then, 54 | ElseClause: elseClause, 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /nodes/stmt-returnStatement.go: -------------------------------------------------------------------------------- 1 | package nodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/lexer" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | ) 8 | 9 | // ReturnStatementNode like: return "Yo mama"; there, get rect. 10 | type ReturnStatementNode struct { 11 | StatementNode 12 | 13 | Keyword lexer.Token 14 | Expression ExpressionNode 15 | } 16 | 17 | // NodeType Copy + Paste 18 | func (ReturnStatementNode) NodeType() NodeType { return ReturnStatement } 19 | 20 | // Position returns the starting line and column, and the total length of the statement 21 | // The starting line and column aren't always the absolute beginning of the statement just what's most 22 | // convenient. 23 | func (node ReturnStatementNode) Span() print.TextSpan { 24 | return node.Keyword.Span.SpanBetween(node.Expression.Span()) 25 | } 26 | 27 | // Print Prints beautiful stuff in console 28 | func (node ReturnStatementNode) Print(indent string) { 29 | print.PrintC(print.Green, indent+"└ ReturnStatementNode") 30 | fmt.Printf("%s └ Keyword: %s\n", indent, node.Keyword.Kind) 31 | 32 | if node.Expression == nil { 33 | fmt.Printf("%s └ Expression: none\n", indent) 34 | } else { 35 | fmt.Println(indent + " └ Expression: ") 36 | node.Expression.Print(indent + " ") 37 | } 38 | } 39 | 40 | // "constructor" / ooga booga OOP cave man brain - Same -_- 41 | func CreateReturnStatementNode(keyword lexer.Token, expression ExpressionNode) ReturnStatementNode { 42 | return ReturnStatementNode{ 43 | Keyword: keyword, 44 | Expression: expression, 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /nodes/stmt-variableDeclaration.go: -------------------------------------------------------------------------------- 1 | package nodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/lexer" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | ) 8 | 9 | // basic global statement member 10 | type VariableDeclarationStatementNode struct { 11 | StatementNode 12 | 13 | Keyword lexer.Token 14 | TypeClause TypeClauseNode 15 | Identifier lexer.Token 16 | AssignToken lexer.Token 17 | Initializer ExpressionNode 18 | } 19 | 20 | // implement node type from interface 21 | func (VariableDeclarationStatementNode) NodeType() NodeType { return VariableDeclaration } 22 | 23 | // Position returns the starting line and column, and the total length of the statement 24 | // The starting line and column aren't always the absolute beginning of the statement just what's most 25 | // convenient. 26 | func (node VariableDeclarationStatementNode) Span() print.TextSpan { 27 | span := node.Keyword.Span.SpanBetween(node.Identifier.Span) 28 | 29 | if node.Initializer != nil { 30 | span = span.SpanBetween(node.Initializer.Span()) 31 | } 32 | 33 | return span 34 | } 35 | 36 | // node print function 37 | func (node VariableDeclarationStatementNode) Print(indent string) { 38 | print.PrintC(print.Green, indent+"└ VariableDeclarationStatementNode") 39 | fmt.Printf("%s └ Keyword: %s\n", indent, node.Keyword.Kind) 40 | 41 | if !node.TypeClause.ClauseIsSet { 42 | fmt.Printf("%s └ TypeClause: none\n", indent) 43 | } else { 44 | fmt.Println(indent + " └ TypeClause: ") 45 | node.TypeClause.Print(indent + " ") 46 | } 47 | 48 | fmt.Printf("%s └ Identifier: %s\n", indent, node.Identifier.Value) 49 | 50 | if node.Initializer != nil { 51 | fmt.Println(indent + " └ Initializer: ") 52 | node.Initializer.Print(indent + " ") 53 | } 54 | } 55 | 56 | // "constructor" / ooga booga OOP cave man brain 57 | func CreateVariableDeclarationStatementNode(kw lexer.Token, typeClause TypeClauseNode, id lexer.Token, assign lexer.Token, init ExpressionNode) VariableDeclarationStatementNode { 58 | return VariableDeclarationStatementNode{ 59 | Keyword: kw, 60 | TypeClause: typeClause, 61 | Identifier: id, 62 | AssignToken: assign, 63 | Initializer: init, 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /nodes/stmt-whileStatement.go: -------------------------------------------------------------------------------- 1 | package nodes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/lexer" 6 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 7 | ) 8 | 9 | // WhileStatementNode joke comments get old after awhile 10 | type WhileStatementNode struct { 11 | StatementNode 12 | 13 | Keyword lexer.Token 14 | Condition ExpressionNode 15 | Statement StatementNode 16 | } 17 | 18 | // NodeType Copy + Paste again 19 | func (WhileStatementNode) NodeType() NodeType { return WhileStatement } 20 | 21 | // Position returns the starting line and column, and the total length of the statement 22 | // The starting line and column aren't always the absolute beginning of the statement just what's most 23 | // convenient. 24 | // We don't process the statement for WhileStatementNode because it do be chonky 25 | func (node WhileStatementNode) Span() print.TextSpan { 26 | return node.Keyword.Span.SpanBetween(node.Statement.Span()) 27 | } 28 | 29 | // Print Prints beautiful stuff in console 30 | func (node WhileStatementNode) Print(indent string) { 31 | print.PrintC(print.Green, indent+"└ WhileStatementNode") 32 | fmt.Printf("%s └ Keyword: %s\n", indent, node.Keyword.Kind) 33 | fmt.Println(indent + " └ Condition: ") 34 | node.Condition.Print(indent + " ") 35 | fmt.Println(indent + " └ Statement: ") 36 | node.Statement.Print(indent + " ") 37 | } 38 | 39 | // "constructor" / ooga booga OOP cave man brain - Same -_- 40 | func CreateWhileStatementNode(keyword lexer.Token, condition ExpressionNode, statement StatementNode) WhileStatementNode { 41 | return WhileStatementNode{ 42 | Keyword: keyword, 43 | Condition: condition, 44 | Statement: statement, 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /nodes/syntaxnode.go: -------------------------------------------------------------------------------- 1 | package nodes 2 | 3 | import print2 "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 4 | 5 | // very cool interface for creating syntax nodes 6 | type SyntaxNode interface { 7 | NodeType() NodeType 8 | Span() print2.TextSpan // exact text position of this node 9 | Print(indent string) 10 | // only type atm, might contain more stuff like text-location later 11 | } 12 | 13 | // very cool interface for creating statements 14 | // (ik this isnt very revolutionary but i just like to organise stuff) 15 | type StatementNode interface { 16 | SyntaxNode 17 | } 18 | 19 | // very cool interface for creating members 20 | // (again, organisation.) 21 | type MemberNode interface { 22 | SyntaxNode 23 | } 24 | 25 | // very cool interface for creating expressions 26 | // (craaaaazy ikr) 27 | type ExpressionNode interface { 28 | SyntaxNode 29 | } 30 | 31 | // cool node type Enum straight up stolen from ReCT v1.0 32 | type NodeType string 33 | 34 | const ( 35 | // i am basing these objects off of the rect 1.0 source 36 | // -> https://github.com/RedCubeDev-ByteSpace/ReCT/tree/834776cbf0ad97da0e6441835f1bc19d903f115b/ReCT/CodeAnalysis/Syntax 37 | 38 | // Members 39 | // ------- 40 | GlobalStatement NodeType = "Global Statement" 41 | FunctionDeclaration NodeType = "Function Declaration" 42 | ExternalFunctionDeclaration NodeType = "External Function Declaration" 43 | ClassDeclaration NodeType = "Class Declaration" 44 | StructDeclaration NodeType = "Struct Declaration" 45 | EnumDeclaration NodeType = "Enum Declaration" 46 | PackageReference NodeType = "Package Reference" 47 | PackageAlias NodeType = "Package Alias" 48 | PackageUse NodeType = "Package Use" 49 | 50 | // General 51 | // ------- 52 | Parameter NodeType = "Parameter" 53 | TypeClause NodeType = "Type Clause" 54 | 55 | // Statements 56 | // ---------- 57 | BlockStatement NodeType = "Block Statement" 58 | VariableDeclaration NodeType = "Variable Declaration" 59 | IfStatement NodeType = "If Statement" 60 | ElseClause NodeType = "Else Clause" 61 | ReturnStatement NodeType = "Return Statement" 62 | ForStatement NodeType = "For Statement" 63 | WhileStatement NodeType = "While Statement" 64 | BreakStatement NodeType = "Break Statement" 65 | ContinueStatement NodeType = "Continue Statement" 66 | FromToStatement NodeType = "FromTo Statement" 67 | ExpressionStatement NodeType = "Expression Statement" 68 | 69 | // Expressions 70 | // ----------- 71 | LiteralExpression NodeType = "Literal Expression" 72 | ParenthesisedExpression NodeType = "Parenthesised Expression" 73 | NameExpression NodeType = "Name Expression" 74 | AssignmentExpression NodeType = "Assignment Expression" 75 | CallExpression NodeType = "Call Expression" 76 | PackageCallExpression NodeType = "PackageCall Expression" 77 | UnaryExpression NodeType = "Unary Expression" 78 | BinaryExpression NodeType = "Binary Expression" 79 | VariableEditorExpression NodeType = "VariableEditor Expression" 80 | TypeCallExpression NodeType = "TypeCall Expression" 81 | ClassFieldAccessExpression NodeType = "ClassFieldAccess Expression" 82 | ClassFieldAssignmentExpression NodeType = "ClassFieldAssignment Expression" 83 | ArrayAccessExpression NodeType = "ArrayAccess Expression" 84 | ArrayAssignmentExpression NodeType = "ArrayAssignment Expression" 85 | MakeExpression NodeType = "Make Expression" 86 | MakeArrayExpression NodeType = "MakeArray Expression" 87 | TernaryExpression NodeType = "Ternary Expression" 88 | ReferenceExpression NodeType = "Reference Expression" 89 | DereferenceExpression NodeType = "Dereference Expression" 90 | MakeStructExpression NodeType = "MakeStruct Expression" 91 | LambdaExpression NodeType = "Lambda Expression" 92 | ThisExpression NodeType = "This Expression" 93 | ) 94 | -------------------------------------------------------------------------------- /packages/Dictionary/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Mauro Baladés 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. 22 | -------------------------------------------------------------------------------- /packages/Dictionary/README.md: -------------------------------------------------------------------------------- 1 | # rect-dictionaries 2 | Dictionaries support for the rect programming language 3 | -------------------------------------------------------------------------------- /packages/pkginfo.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReCT-Lang/ReCT-Go-Compiler/169fbabbf91c00b6b0ecec34c4e112c46dd0fe35/packages/pkginfo.db -------------------------------------------------------------------------------- /packages/sys.bc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReCT-Lang/ReCT-Go-Compiler/169fbabbf91c00b6b0ecec34c4e112c46dd0fe35/packages/sys.bc -------------------------------------------------------------------------------- /parser/README.md: -------------------------------------------------------------------------------- 1 | # ReCT Parser 2 | I decided to give each statement and expression its own class / type like how I did back in C# ReCT. 3 | If this is a stupid idea, please just feel free to punch me! 4 | \- RedCube -------------------------------------------------------------------------------- /print/textspan.go: -------------------------------------------------------------------------------- 1 | package print 2 | 3 | type TextSpan struct { 4 | // the file this span is in 5 | File string 6 | 7 | // the starting and ending indexes of this text span 8 | StartIndex int 9 | EndIndex int 10 | 11 | // starting position 12 | StartLine int 13 | StartColumn int 14 | 15 | // ending position 16 | EndLine int 17 | EndColumn int 18 | } 19 | 20 | func (span1 TextSpan) SpanBetween(span2 TextSpan) TextSpan { 21 | // null checks 22 | if span1.File == "" && span2.File == "" { 23 | return TextSpan{} 24 | } else if span1.File == "" { 25 | return span2 26 | } else if span2.File == "" { 27 | return span1 28 | } 29 | 30 | // we good 31 | var first TextSpan 32 | var last TextSpan 33 | 34 | if span1.StartIndex < span2.StartIndex { 35 | first = span1 36 | } else { 37 | first = span2 38 | } 39 | 40 | if span1.EndIndex > span2.EndIndex { 41 | last = span1 42 | } else { 43 | last = span2 44 | } 45 | 46 | var union TextSpan 47 | union.File = span1.File 48 | 49 | union.StartIndex = first.StartIndex 50 | union.EndIndex = last.EndIndex 51 | 52 | union.StartLine = first.StartLine 53 | union.EndLine = last.EndLine 54 | 55 | union.StartColumn = first.StartColumn 56 | union.EndColumn = last.EndColumn 57 | 58 | return union 59 | } 60 | -------------------------------------------------------------------------------- /rps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReCT-Lang/ReCT-Go-Compiler/169fbabbf91c00b6b0ecec34c4e112c46dd0fe35/rps -------------------------------------------------------------------------------- /rules/rules.go: -------------------------------------------------------------------------------- 1 | package rules 2 | 3 | import "github.com/ReCT-Lang/ReCT-Go-Compiler/lexer" 4 | 5 | // rules: this package is for holding basic language rules like operator order 6 | // --------------------------------------------------------------------------- 7 | 8 | func GetUnaryOperatorPrecedence(tok lexer.Token) int { 9 | switch tok.Kind { 10 | 11 | case lexer.PlusToken, 12 | lexer.MinusToken, 13 | lexer.NotToken: 14 | return 6 // always one higher than the highest binary operator 15 | 16 | default: 17 | return 0 18 | } 19 | } 20 | 21 | func GetBinaryOperatorPrecedence(tok lexer.Token) int { 22 | switch tok.Kind { 23 | 24 | case lexer.StarToken, lexer.SlashToken, lexer.ModulusToken: 25 | return 5 26 | 27 | case lexer.PlusToken, lexer.MinusToken: 28 | return 4 29 | 30 | case lexer.EqualsToken, 31 | lexer.NotEqualsToken, 32 | lexer.LessThanToken, 33 | lexer.GreaterThanToken, 34 | lexer.LessEqualsToken, 35 | lexer.GreaterEqualsToken, 36 | lexer.ShiftLeftToken, 37 | lexer.ShiftRightToken: 38 | return 3 39 | 40 | case lexer.AmpersandsToken: 41 | return 2 42 | 43 | case lexer.PipesToken, 44 | lexer.HatToken: 45 | return 1 46 | 47 | default: 48 | return 0 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /run_lin.sh: -------------------------------------------------------------------------------- 1 | ./rgoc -llvm -o ./out.ll $1 2 | 3 | opt ./out.ll > ./out.bc 4 | opt ./packages/sys.ll > ./packages/sys.bc 5 | llvm-link ./out.bc ./systemlib/systemlib_lin.bc ./packages/sys.bc > ./program.bc 6 | clang -lm -pthread -rdynamic ./program.bc -o ./program 7 | 8 | ./program -------------------------------------------------------------------------------- /symbols/README.md: -------------------------------------------------------------------------------- 1 | # ReCT Symbols 2 | This package contains all of ReCTs symbols. These are things like type-symbols function-symbols and variable-symbols. 3 | They are used by the Binder to string the syntax tree together into a concrete program, making sure that variables and functions being called exist, and that datatypes match up. -------------------------------------------------------------------------------- /symbols/classSymbol.go: -------------------------------------------------------------------------------- 1 | package symbols 2 | 3 | import ( 4 | "github.com/ReCT-Lang/ReCT-Go-Compiler/nodes" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 6 | 7 | "github.com/llir/llvm/ir/types" 8 | ) 9 | 10 | type ClassSymbol struct { 11 | Symbol 12 | 13 | Exists bool 14 | 15 | Type TypeSymbol 16 | IRType types.Type 17 | 18 | Package PackageSymbol 19 | 20 | Name string 21 | Declaration nodes.ClassDeclarationMember 22 | Functions []FunctionSymbol 23 | Fields []VariableSymbol 24 | } 25 | 26 | // implement the symbol interface 27 | func (ClassSymbol) SymbolType() SymbolType { return Class } 28 | func (s ClassSymbol) SymbolName() string { return s.Name } 29 | 30 | func (sym ClassSymbol) Print(indent string) { 31 | print.PrintC(print.Magenta, indent+"└ ClassSymbol ["+sym.Name+"]") 32 | } 33 | 34 | func (s ClassSymbol) Fingerprint() string { 35 | id := "C_" + s.Name + "_" 36 | return id 37 | } 38 | 39 | // constructor 40 | func CreateClassSymbol(name string, declration nodes.ClassDeclarationMember, functions []FunctionSymbol, fields []VariableSymbol, pck PackageSymbol) ClassSymbol { 41 | sym := ClassSymbol{ 42 | Exists: true, 43 | Name: name, 44 | Declaration: declration, 45 | Functions: functions, 46 | Fields: fields, 47 | Package: pck, 48 | } 49 | 50 | sym.Type = CreateTypeSymbol(name, make([]TypeSymbol, 0), true, true, false, pck, sym) 51 | return sym 52 | } 53 | -------------------------------------------------------------------------------- /symbols/enumSymbol.go: -------------------------------------------------------------------------------- 1 | package symbols 2 | 3 | import ( 4 | "github.com/ReCT-Lang/ReCT-Go-Compiler/nodes" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 6 | ) 7 | 8 | type EnumSymbol struct { 9 | Symbol 10 | 11 | Exists bool 12 | 13 | Type TypeSymbol 14 | 15 | Name string 16 | Declaration nodes.EnumDeclarationMember 17 | Fields map[string]int 18 | } 19 | 20 | // implement the symbol interface 21 | func (EnumSymbol) SymbolType() SymbolType { return Enum } 22 | func (s EnumSymbol) SymbolName() string { return s.Name } 23 | 24 | func (sym EnumSymbol) Print(indent string) { 25 | print.PrintC(print.Magenta, indent+"└ EnumSymbol ["+sym.Name+"]") 26 | } 27 | 28 | func (s EnumSymbol) Fingerprint() string { 29 | id := "E_" + s.Name + "_" 30 | return id 31 | } 32 | 33 | // constructor 34 | func CreateEnumSymbol(name string, declaration nodes.EnumDeclarationMember, fields map[string]int) EnumSymbol { 35 | sym := EnumSymbol{ 36 | Exists: true, 37 | Name: name, 38 | Declaration: declaration, 39 | Fields: fields, 40 | } 41 | 42 | sym.Type = CreateTypeSymbol(name, make([]TypeSymbol, 0), false, false, true, PackageSymbol{}, sym) 43 | return sym 44 | } 45 | -------------------------------------------------------------------------------- /symbols/functionSymbol.go: -------------------------------------------------------------------------------- 1 | package symbols 2 | 3 | import ( 4 | "github.com/ReCT-Lang/ReCT-Go-Compiler/nodes" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 6 | 7 | "github.com/llir/llvm/ir" 8 | ) 9 | 10 | type FunctionSymbol struct { 11 | Symbol 12 | 13 | Exists bool 14 | BuiltIn bool 15 | Public bool 16 | External bool 17 | Variadic bool 18 | Adapted bool 19 | 20 | IRFunction *ir.Func 21 | 22 | Name string 23 | Parameters []ParameterSymbol 24 | Type TypeSymbol 25 | Declaration nodes.FunctionDeclarationMember 26 | } 27 | 28 | // implement the symbol interface 29 | func (FunctionSymbol) SymbolType() SymbolType { return Function } 30 | func (s FunctionSymbol) SymbolName() string { return s.Name } 31 | 32 | func (sym FunctionSymbol) Print(indent string) { 33 | if sym.BuiltIn { 34 | print.PrintC(print.Cyan, indent+"└ FunctionSymbol ["+sym.Name+"]") 35 | } else { 36 | print.PrintC(print.Magenta, indent+"└ FunctionSymbol ["+sym.Name+"]") 37 | } 38 | } 39 | 40 | func (s FunctionSymbol) Fingerprint() string { 41 | id := "F_" + s.Name + "_" 42 | 43 | for _, param := range s.Parameters { 44 | id += "[" + param.Type.Fingerprint() + "]" 45 | } 46 | 47 | id += s.Type.Name 48 | return id 49 | } 50 | 51 | // constructor 52 | func CreateFunctionSymbol(name string, params []ParameterSymbol, typeSymbol TypeSymbol, declaration nodes.FunctionDeclarationMember, public bool) FunctionSymbol { 53 | return FunctionSymbol{ 54 | Exists: true, 55 | Name: name, 56 | Parameters: params, 57 | Type: typeSymbol, 58 | Declaration: declaration, 59 | Public: public, 60 | } 61 | } 62 | 63 | func CreateExternalFunctionSymbol(name string, declaration nodes.FunctionDeclarationMember, params []ParameterSymbol, typeSymbol TypeSymbol, variadic bool, adapted bool) FunctionSymbol { 64 | return FunctionSymbol{ 65 | Exists: true, 66 | Name: name, 67 | Declaration: declaration, 68 | Parameters: params, 69 | Type: typeSymbol, 70 | External: true, 71 | Variadic: variadic, 72 | Adapted: adapted, 73 | Public: true, 74 | } 75 | } 76 | 77 | func CreateBuiltInFunctionSymbol(name string, params []ParameterSymbol, typeSymbol TypeSymbol, declaration nodes.FunctionDeclarationMember) FunctionSymbol { 78 | return FunctionSymbol{ 79 | Exists: true, 80 | BuiltIn: true, 81 | Name: name, 82 | Parameters: params, 83 | Type: typeSymbol, 84 | Declaration: declaration, 85 | Public: true, 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /symbols/globalVariableSymbol.go: -------------------------------------------------------------------------------- 1 | package symbols 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 6 | ) 7 | 8 | type GlobalVariableSymbol struct { 9 | VariableSymbol 10 | 11 | Name string 12 | ReadOnly bool 13 | Type TypeSymbol 14 | UniqueID int 15 | } 16 | 17 | // implement the symbol interface 18 | func (GlobalVariableSymbol) SymbolType() SymbolType { return GlobalVariable } 19 | func (s GlobalVariableSymbol) SymbolName() string { return s.Name } 20 | 21 | func (sym GlobalVariableSymbol) Print(indent string) { 22 | print.PrintC(print.Magenta, indent+"└ GlobalVariableSymbol ["+sym.Name+"]") 23 | } 24 | 25 | // implement the var interface 26 | func (GlobalVariableSymbol) IsGlobal() bool { return true } 27 | func (s GlobalVariableSymbol) IsReadOnly() bool { return s.ReadOnly } 28 | func (s GlobalVariableSymbol) VarType() TypeSymbol { return s.Type } 29 | func (s GlobalVariableSymbol) Fingerprint() string { return fmt.Sprintf("VG_%d", s.UniqueID) } 30 | 31 | // constructor 32 | func CreateGlobalVariableSymbol(name string, readonly bool, typeSymbol TypeSymbol) GlobalVariableSymbol { 33 | variableCounter++ 34 | return GlobalVariableSymbol{ 35 | Name: name, 36 | ReadOnly: readonly, 37 | Type: typeSymbol, 38 | UniqueID: variableCounter, 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /symbols/localVariableSymbol.go: -------------------------------------------------------------------------------- 1 | package symbols 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 6 | ) 7 | 8 | type LocalVariableSymbol struct { 9 | VariableSymbol 10 | 11 | Name string 12 | ReadOnly bool 13 | Type TypeSymbol 14 | UniqueID int 15 | } 16 | 17 | // implement the symbol interface 18 | func (LocalVariableSymbol) SymbolType() SymbolType { return LocalVariable } 19 | func (s LocalVariableSymbol) SymbolName() string { return s.Name } 20 | 21 | func (sym LocalVariableSymbol) Print(indent string) { 22 | print.PrintC(print.Magenta, indent+"└ LocalVariableSymbol ["+sym.Name+"]") 23 | } 24 | 25 | // implement the var interface 26 | func (LocalVariableSymbol) IsGlobal() bool { return false } 27 | func (s LocalVariableSymbol) IsReadOnly() bool { return s.ReadOnly } 28 | func (s LocalVariableSymbol) VarType() TypeSymbol { return s.Type } 29 | func (s LocalVariableSymbol) Fingerprint() string { return fmt.Sprintf("VL_%d", s.UniqueID) } 30 | 31 | // constructor 32 | func CreateLocalVariableSymbol(name string, readonly bool, typeSymbol TypeSymbol) LocalVariableSymbol { 33 | variableCounter++ 34 | return LocalVariableSymbol{ 35 | Name: name, 36 | ReadOnly: readonly, 37 | Type: typeSymbol, 38 | UniqueID: variableCounter, 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /symbols/packageSymbol.go: -------------------------------------------------------------------------------- 1 | package symbols 2 | 3 | import ( 4 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 5 | 6 | "github.com/llir/llvm/ir" 7 | ) 8 | 9 | type PackageSymbol struct { 10 | Symbol 11 | 12 | Exists bool 13 | IsAlias bool 14 | Original *PackageSymbol 15 | 16 | Name string 17 | Functions []FunctionSymbol 18 | Classes []ClassSymbol 19 | 20 | Module *ir.Module 21 | ErrorLocation print.TextSpan 22 | } 23 | 24 | // implement the symbol interface 25 | func (PackageSymbol) SymbolType() SymbolType { return Package } 26 | func (s PackageSymbol) SymbolName() string { return s.Name } 27 | 28 | func (sym PackageSymbol) Print(indent string) { 29 | print.PrintC(print.Magenta, indent+"└ PackageSymbol ["+sym.Name+"]") 30 | } 31 | 32 | func (s PackageSymbol) Fingerprint() string { 33 | id := "P_" + s.Name + "_" 34 | return id 35 | } 36 | 37 | // constructor 38 | func CreatePackageSymbol(name string, functions []FunctionSymbol, classes []ClassSymbol, module *ir.Module, errorLocation print.TextSpan) PackageSymbol { 39 | return PackageSymbol{ 40 | Exists: true, 41 | Name: name, 42 | Functions: functions, 43 | Classes: classes, 44 | Module: module, 45 | ErrorLocation: errorLocation, 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /symbols/parameterSymbol.go: -------------------------------------------------------------------------------- 1 | package symbols 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 6 | ) 7 | 8 | type ParameterSymbol struct { 9 | VariableSymbol 10 | 11 | Name string 12 | Ordinal int 13 | Type TypeSymbol 14 | UniqueID int 15 | } 16 | 17 | // implement the symbol interface 18 | func (ParameterSymbol) SymbolType() SymbolType { return Parameter } 19 | func (s ParameterSymbol) SymbolName() string { return s.Name } 20 | 21 | func (sym ParameterSymbol) Print(indent string) { 22 | print.PrintC(print.Magenta, indent+"└ ParameterSymbol ["+sym.Name+"]") 23 | } 24 | 25 | // implement the var interface 26 | func (ParameterSymbol) IsGlobal() bool { return false } 27 | func (s ParameterSymbol) IsReadOnly() bool { return true } 28 | func (s ParameterSymbol) VarType() TypeSymbol { return s.Type } 29 | func (s ParameterSymbol) Fingerprint() string { return fmt.Sprintf("VP_%d", s.UniqueID) } 30 | 31 | // constructor 32 | func CreateParameterSymbol(name string, ordinal int, typeSymbol TypeSymbol) ParameterSymbol { 33 | variableCounter++ 34 | return ParameterSymbol{ 35 | Name: name, 36 | Ordinal: ordinal, 37 | Type: typeSymbol, 38 | UniqueID: variableCounter, 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /symbols/structSymbol.go: -------------------------------------------------------------------------------- 1 | package symbols 2 | 3 | import ( 4 | "github.com/ReCT-Lang/ReCT-Go-Compiler/nodes" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 6 | 7 | "github.com/llir/llvm/ir/types" 8 | ) 9 | 10 | type StructSymbol struct { 11 | Symbol 12 | 13 | Exists bool 14 | 15 | Type TypeSymbol 16 | IRType types.Type 17 | 18 | Name string 19 | Declaration nodes.StructDeclarationMember 20 | Fields []VariableSymbol 21 | } 22 | 23 | // implement the symbol interface 24 | func (StructSymbol) SymbolType() SymbolType { return Struct } 25 | func (s StructSymbol) SymbolName() string { return s.Name } 26 | 27 | func (sym StructSymbol) Print(indent string) { 28 | print.PrintC(print.Magenta, indent+"└ StructSymbol ["+sym.Name+"]") 29 | } 30 | 31 | func (s StructSymbol) Fingerprint() string { 32 | id := "S_" + s.Name + "_" 33 | return id 34 | } 35 | 36 | // constructor 37 | func CreateStructSymbol(name string, declaration nodes.StructDeclarationMember, fields []VariableSymbol) StructSymbol { 38 | sym := StructSymbol{ 39 | Exists: true, 40 | Name: name, 41 | Declaration: declaration, 42 | Fields: fields, 43 | } 44 | 45 | sym.Type = CreateTypeSymbol(name, make([]TypeSymbol, 0), false, true, false, PackageSymbol{}, sym) 46 | 47 | return sym 48 | } 49 | -------------------------------------------------------------------------------- /symbols/symbol.go: -------------------------------------------------------------------------------- 1 | package symbols 2 | 3 | import ( 4 | "fmt" 5 | print2 "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 6 | ) 7 | 8 | type Symbol interface { 9 | SymbolType() SymbolType 10 | SymbolName() string 11 | Print(indent string) 12 | Fingerprint() string 13 | } 14 | 15 | var variableCounter = 0 16 | 17 | type VariableSymbol interface { 18 | Symbol 19 | 20 | IsReadOnly() bool 21 | IsGlobal() bool 22 | VarType() TypeSymbol 23 | Declaration() print2.TextSpan 24 | } 25 | 26 | var tempCounter = 0 27 | 28 | func GetTempName() string { 29 | tempCounter++ 30 | return fmt.Sprintf("TMP_%d", tempCounter) 31 | } 32 | 33 | var lambdaCounter = 0 34 | 35 | func GetLambdaName() string { 36 | lambdaCounter++ 37 | return fmt.Sprintf("LAMBDA_%d", lambdaCounter) 38 | } 39 | 40 | // types of symbols 41 | type SymbolType string 42 | 43 | const ( 44 | Function SymbolType = "FunctionSymbol" 45 | Class SymbolType = "ClassSymbol" 46 | Struct SymbolType = "StructSymbol" 47 | Enum SymbolType = "EnumSymbol" 48 | GlobalVariable SymbolType = "GlobalVariableSymbol" 49 | LocalVariable SymbolType = "LocalVariableSymbol" 50 | Parameter SymbolType = "ParameterSymbol" 51 | Type SymbolType = "TypeSymbol" 52 | Package SymbolType = "PackageSymbol" 53 | ) 54 | -------------------------------------------------------------------------------- /symbols/typeFunctionSymbol.go: -------------------------------------------------------------------------------- 1 | package symbols 2 | 3 | import ( 4 | "github.com/ReCT-Lang/ReCT-Go-Compiler/nodes" 5 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 6 | ) 7 | 8 | type TypeFunctionSymbol struct { 9 | Symbol 10 | 11 | Exists bool 12 | BuiltIn bool 13 | 14 | Name string 15 | Parameters []ParameterSymbol 16 | Type TypeSymbol 17 | Declaration nodes.FunctionDeclarationMember 18 | OriginType TypeSymbol // This is the data type of function access call like string->Split() 19 | } 20 | 21 | // implement the symbol interface 22 | func (TypeFunctionSymbol) SymbolType() SymbolType { return Function } 23 | func (sym TypeFunctionSymbol) SymbolName() string { return sym.Name } 24 | 25 | func (sym TypeFunctionSymbol) Print(indent string) { 26 | if sym.BuiltIn { 27 | print.PrintC(print.Cyan, indent+"└ FunctionSymbol ["+sym.Name+"]") 28 | } else { 29 | print.PrintC(print.Magenta, indent+"└ FunctionSymbol ["+sym.Name+"]") 30 | } 31 | } 32 | 33 | func (sym TypeFunctionSymbol) Fingerprint() string { 34 | id := "TF_" + sym.OriginType.Fingerprint() + "_" + sym.Name + "_" 35 | 36 | for _, param := range sym.Parameters { 37 | id += "[" + param.Type.Fingerprint() + "]" 38 | } 39 | 40 | id += sym.Type.Name 41 | return id 42 | } 43 | 44 | // constructor 45 | func CreateTypeFunctionSymbol( 46 | name string, 47 | params []ParameterSymbol, 48 | typeSymbol TypeSymbol, 49 | declaration nodes.FunctionDeclarationMember, 50 | origin TypeSymbol, 51 | ) TypeFunctionSymbol { 52 | return TypeFunctionSymbol{ 53 | Exists: true, 54 | Name: name, 55 | Parameters: params, 56 | Type: typeSymbol, 57 | Declaration: declaration, 58 | } 59 | } 60 | 61 | func CreateBuiltInTypeFunctionSymbol( 62 | name string, 63 | params []ParameterSymbol, 64 | typeSymbol TypeSymbol, 65 | declaration nodes.FunctionDeclarationMember, 66 | origin TypeSymbol, 67 | ) TypeFunctionSymbol { 68 | return TypeFunctionSymbol{ 69 | Exists: true, 70 | BuiltIn: true, 71 | Name: name, 72 | Parameters: params, 73 | Type: typeSymbol, 74 | Declaration: declaration, 75 | OriginType: origin, 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /symbols/typeSymbol.go: -------------------------------------------------------------------------------- 1 | package symbols 2 | 3 | import ( 4 | "github.com/ReCT-Lang/ReCT-Go-Compiler/print" 5 | ) 6 | 7 | type TypeSymbol struct { 8 | Symbol 9 | 10 | Name string 11 | SubTypes []TypeSymbol 12 | IsObject bool 13 | IsUserDefined bool 14 | IsEnum bool 15 | 16 | SourceSymbol Symbol 17 | Package PackageSymbol 18 | } 19 | 20 | // implement the interface 21 | func (TypeSymbol) SymbolType() SymbolType { return Type } 22 | func (s TypeSymbol) SymbolName() string { return s.Name } 23 | 24 | func (sym TypeSymbol) Print(indent string) { 25 | print.PrintC(print.Magenta, indent+"└ TypeSymbol ["+sym.Fingerprint()+"]") 26 | } 27 | 28 | // a unique identifier for each type 29 | func (sym TypeSymbol) Fingerprint() string { 30 | id := "T" 31 | 32 | if sym.IsObject { 33 | id += "O" 34 | } 35 | 36 | id += "_" + sym.Name + "_[" 37 | 38 | for _, subtype := range sym.SubTypes { 39 | if subtype.Name == "array" { 40 | id += subtype.Fingerprint() + ";" 41 | } else { 42 | id += subtype.Name + ";" 43 | } 44 | } 45 | 46 | id += "]" 47 | 48 | return id 49 | } 50 | 51 | // constructor 52 | func CreateTypeSymbol(name string, subTypes []TypeSymbol, isObject bool, isUserDefined bool, isEnum bool, pck PackageSymbol, src Symbol) TypeSymbol { 53 | return TypeSymbol{ 54 | Name: name, 55 | SubTypes: subTypes, 56 | IsObject: isObject, 57 | IsUserDefined: isUserDefined, 58 | IsEnum: isEnum, 59 | Package: pck, 60 | SourceSymbol: src, 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /systemlib/exceptions.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "objects.h" 7 | #include "exceptions.h" 8 | 9 | // Very advanced ReCT exceptions 10 | // ----------------------------- 11 | 12 | // some ANSI colors for the printout 13 | #define BLK "\e[0;30m" 14 | #define RED "\e[0;31m" 15 | #define GRN "\e[0;32m" 16 | #define YEL "\e[0;33m" 17 | #define BLU "\e[0;34m" 18 | #define MAG "\e[0;35m" 19 | #define CYN "\e[0;36m" 20 | #define WHT "\e[0;37m" 21 | 22 | #define BBLK "\e[1;30m" 23 | #define BRED "\e[1;31m" 24 | #define BGRN "\e[1;32m" 25 | #define BYEL "\e[1;33m" 26 | #define BBLU "\e[1;34m" 27 | #define BMAG "\e[1;35m" 28 | #define BCYN "\e[1;36m" 29 | #define BWHT "\e[1;37m" 30 | 31 | #define RESET "\e[0m" 32 | 33 | // the actual throw message 34 | void exc_Throw(char *message) { 35 | // exception format: 36 | // [RUNTIME] Encountered Exception! '' 37 | // [Stacktrace] 38 | // ... 39 | 40 | // error head 41 | printf("%s[RUNTIME] %sEncountered Exception! %s'%s'\n", BRED, RED, BRED, message); 42 | 43 | // stacktrace 44 | printf("%s[STACKTRACE] %s\n", BYEL, YEL); 45 | 46 | // get the call stack 47 | void* callstack[128]; 48 | int frames = backtrace(callstack, 128); 49 | char** strs = backtrace_symbols(callstack, frames); 50 | 51 | // print out the call stack 52 | // stop printing as soon as we get to non-program things 53 | for (int i = 1; i < frames; ++i) { 54 | // check if this string is from an external lib 55 | char *foundSO = strstr(strs[i], ".so"); 56 | char *foundDLL = strstr(strs[i], ".dll"); 57 | 58 | // if so, destroy the loop 59 | if (foundSO) break; 60 | if (foundDLL) break; 61 | 62 | printf("%s\n", strs[i]); 63 | } 64 | 65 | // destroy the strings 66 | free(strs); 67 | 68 | // die(); 69 | exit(-1); 70 | } 71 | 72 | // shortcut for null errors 73 | void exc_ThrowIfNull(void* pointer) { 74 | if (pointer == NULL) 75 | exc_Throw("Null-Pointer exception! The given reference was null."); 76 | } 77 | 78 | // shortcut for invalThreadid casting errors 79 | void exc_ThrowIfInvalidCast(class_Any* fromObj, Standard_vTable *to, const char *toFingerprint) { 80 | // source object hasnt been initialized yet 81 | // in that case we allow conversion because NULL is the same, no matter what type 82 | if (fromObj == NULL) return; 83 | 84 | // get the source's vtable for convenience 85 | Standard_vTable from = fromObj->vtable; 86 | 87 | // goal vTable is null, this is not allowed to happen and indicates a broken program 88 | if (to == NULL) 89 | exc_Throw("Conversion vTable for output type could not be found! This indicates a broken executable."); 90 | 91 | // check if the source is the same as the goal already, just casted to something else 92 | if (strcmp(from.fingerprint, toFingerprint) == 0) return; 93 | 94 | // if the goal type is "Any", all objects are always allowed to cast to it 95 | if (strcmp(to->className, "Any") == 0) return; 96 | 97 | // check if the source inherits from the goal 98 | const Standard_vTable *parent = from.parentVTable; 99 | while (parent != NULL) { 100 | // inheritance found 101 | if (strcmp(parent->className, to->className) == 0) return; 102 | 103 | // if not, continue searching up the chain 104 | parent = parent->parentVTable; 105 | } 106 | 107 | // check if the goal inherits from the source 108 | parent = to->parentVTable; 109 | while (parent != NULL) { 110 | // inheritance found 111 | if (strcmp(parent->className, from.className) == 0) return; 112 | 113 | // if not, continue searching up the chain 114 | parent = parent->parentVTable; 115 | } 116 | 117 | // if the names are equal -> show the fingerprints 118 | bool namesAreEqual = strcmp(from.className, to->className) == 0; 119 | 120 | // if all those checks fail -> this cast is invalid 121 | char *errorTpl = "Object of type %s could not be casted to type %s!"; 122 | char *errorMsg = malloc(snprintf(NULL, 0, errorTpl, 123 | namesAreEqual ? from.fingerprint : from.className, 124 | namesAreEqual ? toFingerprint : to->className 125 | ) + 1 126 | ); 127 | sprintf(errorMsg, errorTpl, 128 | namesAreEqual ? from.fingerprint : from.className, 129 | namesAreEqual ? toFingerprint : to->className 130 | ); 131 | 132 | exc_Throw(errorMsg); 133 | } -------------------------------------------------------------------------------- /systemlib/exceptions.h: -------------------------------------------------------------------------------- 1 | #ifndef EXCEPTIONS_H 2 | #define EXCEPTIONS_H 3 | 4 | // define the throwing function (very athletic) 5 | // ============================================ 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | // standard exception throwing 12 | void exc_Throw(char *message); 13 | 14 | // exception shortcuts 15 | void exc_ThrowIfNull(void *pointer); 16 | void exc_ThrowIfInvalidCast(class_Any* from, Standard_vTable *to, const char *toFingerprint); 17 | 18 | #ifdef __cplusplus 19 | } 20 | #endif 21 | 22 | #endif -------------------------------------------------------------------------------- /systemlib/syslib_compile_lin.sh: -------------------------------------------------------------------------------- 1 | #clang ./arc.c -emit-llvm -S -o ./arc.bc 2 | clang ./objects.c -emit-llvm -S -o ./objects.bc 3 | clang ./exceptions.c -emit-llvm -S -o ./exceptions.bc 4 | 5 | #opt ./arc.ll > ./arc.bc 6 | #opt ./objects.ll > ./objects.bc 7 | #opt ./systemlib.ll > ./systemlib.bc 8 | 9 | llvm-link ./objects.bc ./exceptions.bc > ./systemlib_lin.bc 10 | llvm-dis ./systemlib_lin.bc > ./systemlib_lin.ll -------------------------------------------------------------------------------- /systemlib/systemlib_lin.bc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReCT-Lang/ReCT-Go-Compiler/169fbabbf91c00b6b0ecec34c4e112c46dd0fe35/systemlib/systemlib_lin.bc -------------------------------------------------------------------------------- /systempacks/sys.c: -------------------------------------------------------------------------------- 1 | #ifdef _WIN32 2 | #include 3 | #else 4 | #include 5 | #endif 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include "../systemlib/objects.h" 15 | #include "../systemlib/exceptions.h" 16 | 17 | #define BUFFER 1042 18 | 19 | bool isCursorVisible = true; 20 | 21 | void sys_Print(class_String *text) 22 | { 23 | // if theres no string, do a little trolling 24 | if (text == NULL) 25 | printf("\n"); 26 | else 27 | printf("%s\n", text->buffer); 28 | } 29 | 30 | void sys_Write(class_String *text) 31 | { 32 | if (text != NULL) 33 | printf("%s", text->buffer); 34 | } 35 | 36 | class_String* sys_Input() 37 | { 38 | char *str = malloc(sizeof(char) * BUFFER), *err; 39 | int pos; 40 | for(pos = 0; str != NULL && (str[pos] = getchar()) != '\n'; pos++) 41 | { 42 | if(pos % BUFFER == BUFFER - 1) 43 | { 44 | if((err = realloc(str, sizeof(char) * (BUFFER + pos + 1))) == NULL) 45 | free(str); 46 | str = err; 47 | } 48 | } 49 | if(str != NULL) 50 | str[pos] = '\0'; 51 | 52 | class_String *strInstance = (class_String*)GC_MALLOC(sizeof(class_String)); 53 | strInstance->vtable = (Standard_vTable){NULL, "String"}; 54 | strInstance->vtable.fingerprint = "TO_string[]_"; 55 | 56 | String_public_Constructor(strInstance); 57 | String_public_Load(strInstance, str); 58 | 59 | if(str != NULL) 60 | free(str); 61 | 62 | return strInstance; 63 | } 64 | 65 | void sys_Clear() 66 | { 67 | printf("\033[2J\033[H"); 68 | } 69 | 70 | void sys_SetCursor(int x, int y) 71 | { 72 | printf("%c[%d;%df", 0x1B, y, x); 73 | } 74 | 75 | void sys_SetCursorVisible(bool state) 76 | { 77 | isCursorVisible = state; 78 | 79 | if (state) { 80 | printf("\e[?251]"); 81 | return; 82 | } 83 | 84 | printf("\e[?251]"); 85 | } 86 | 87 | bool sys_GetCursorVisible() 88 | { 89 | return isCursorVisible; 90 | } 91 | 92 | int sys_Random(int maxValue) 93 | { 94 | return rand() % maxValue; 95 | } 96 | 97 | void sys_Sleep(int ms) 98 | { 99 | #ifdef _WIN32 100 | Sleep(ms); 101 | #else 102 | usleep(ms * 1000); 103 | #endif 104 | } 105 | 106 | int sys_Sqrt(int num) 107 | { 108 | return (int)floor(sqrt((double)num)); 109 | } 110 | 111 | int sys_Now() 112 | { 113 | return (int)clock(); 114 | } 115 | 116 | class_String *sys_Char(int index) 117 | { 118 | char *singleChar = (char*)malloc(1); 119 | singleChar[0] = (char)index; 120 | 121 | class_String *strInstance = (class_String*)GC_MALLOC(sizeof(class_String)); 122 | strInstance->vtable = (Standard_vTable){NULL, "String"}; 123 | strInstance->vtable.fingerprint = "TO_string[]_"; 124 | 125 | String_public_Constructor(strInstance); 126 | String_public_Load(strInstance, singleChar); 127 | 128 | free(singleChar); 129 | 130 | return strInstance; 131 | } -------------------------------------------------------------------------------- /tests/arrayTest.rct: -------------------------------------------------------------------------------- 1 | // ansi escape 2 | set ESC <- Char(27); 3 | 4 | // create a 10 by 10 2d array 5 | // -------------------------- 6 | var arr2d <- make array[int] array(10); 7 | from (i <- 0) to arr2d->GetLength() -1 8 | arr2d[i] <- make int array(10); 9 | 10 | 11 | // fill the array 12 | // -------------- 13 | from (x <- 0) to 9 14 | from (y <- 0) to 9 15 | arr2d[x][y] <- (x+1) * (y+1) * 2; 16 | 17 | // print out the array with rgb ansi colors 18 | // ---------------------------------------- 19 | from (y <- 0) to 9 20 | { 21 | from (x <- 0) to 9 22 | { 23 | // ANSI color 24 | Write(ESC + "[38;2;"+string(arr2d[x][y])+";"+string(arr2d[x][y])+";"+string(arr2d[x][y])+"m"); 25 | // the char 26 | Write("██"); 27 | } 28 | 29 | Print(""); // newline 30 | } 31 | 32 | // create a string array literal 33 | var strArr <- make string array { "this ", "is ", "a ", "string ", "array" }; 34 | 35 | from (i <- 0) to strArr->GetLength() -1 36 | Write(strArr[i]); 37 | Print(""); 38 | 39 | // create an int array literal 40 | var intArr <- make int array { 100, 200, 300 }; 41 | from (i <- 0) to intArr->GetLength() -1 42 | Write(string(intArr[i]) + ", "); 43 | Print(""); -------------------------------------------------------------------------------- /tests/arrayTest2.rct: -------------------------------------------------------------------------------- 1 | package sys; 2 | 3 | var arr <- make string array(1); 4 | arr[0] <- "some string"; 5 | 6 | var obj <- any(arr); 7 | var damnThatsIllegal <- array[int](obj); 8 | -------------------------------------------------------------------------------- /tests/bitshift.rct: -------------------------------------------------------------------------------- 1 | package sys; 2 | 3 | var val <- 0b10000000000; 4 | 5 | from (i <- 0) to 10 { 6 | sys::Print(string(val)); 7 | val <- val >> 1; 8 | } 9 | -------------------------------------------------------------------------------- /tests/byteTest.rct: -------------------------------------------------------------------------------- 1 | var byte coolByte; 2 | var int coolInt; 3 | 4 | coolByte <- 20; 5 | coolInt <- 10; 6 | 7 | var varSelect <- false; 8 | var varSelect2 <- false; 9 | 10 | Print(string(varSelect ? coolByte : byte(coolInt))); 11 | 12 | var str0 <- "yes"; 13 | var str1 <- "nah"; 14 | 15 | var loopCounter <- 0; 16 | 17 | while(true) 18 | { 19 | // ternary template: 20 | //var string tmp; 21 | //if (varSelect) { 22 | // tmp <- "yes"; 23 | //} else { 24 | // tmp <- "nah"; 25 | //} 26 | //Print(tmp); 27 | 28 | // nested ternary o.O 29 | Print(varSelect 30 | ? "yes" 31 | : (varSelect2 ? "hm" : "no")); 32 | Sleep(1); 33 | 34 | loopCounter++; 35 | if (loopCounter % 3 = 0) varSelect <- !varSelect 36 | if (loopCounter % 10 = 0) varSelect2 <- !varSelect2 37 | } -------------------------------------------------------------------------------- /tests/classTest.rct: -------------------------------------------------------------------------------- 1 | package sys; 2 | 3 | // much class 4 | class SomeClass { 5 | 6 | // instance of another class 7 | set OtherClass otherClass; 8 | set CoolString <- "very cool"; 9 | 10 | function Constructor() { 11 | otherClass <- make OtherClass(); 12 | } 13 | } 14 | 15 | class OtherClass { 16 | set incrediblyCoolNumber <- 100; 17 | set MyCoolerString <- "dun dun dun dun dun dun dun, dududun, BAM BAM"; 18 | } 19 | 20 | while(true) { 21 | var someInstance <- make SomeClass(); 22 | //someInstance->Die(); 23 | sys::Print(someInstance->CoolString); 24 | 25 | var any someAny; 26 | someAny <- any(someInstance); 27 | 28 | var SomeClass instanceAgain; 29 | instanceAgain <- SomeClass(someAny); 30 | sys::Print(someInstance->CoolString); 31 | 32 | sys::Print(someInstance->otherClass->MyCoolerString); 33 | } 34 | 35 | -------------------------------------------------------------------------------- /tests/classlambda.rct: -------------------------------------------------------------------------------- 1 | package sys; 2 | 3 | external clock() long; 4 | 5 | set CoolVar <- 100; 6 | 7 | set function FuncInMain() { 8 | sys::Print("CoolVar is " + string(CoolVar)); 9 | sys::Print("Changing to " + string(CoolVar + 10) + "..."); 10 | CoolVar <- CoolVar + 10; 11 | } 12 | 13 | class SomeClass { 14 | set string Fld <- "cool string"; 15 | set thread Thrd; 16 | 17 | function Constructor() { 18 | main->CoolVar <- 200; 19 | main->FuncInMain->Run(); 20 | sys::Print(string(main->CoolVar)); 21 | 22 | // lmd is automatically defined as action[SomeClass, void] 23 | var lmd <- someOtherFunction; 24 | Thrd <- lmd->RunThread(this); 25 | } 26 | 27 | // nothing special going on with this func 28 | function someOtherFunction() { 29 | Fld <- "cooler string"; 30 | sys::Print("dude imagine being in a different thread"); 31 | } 32 | } 33 | 34 | //while (clock() < 10000000) { 35 | var obj <- make SomeClass(); 36 | sys::Print(obj->Fld + " : " + string(clock())); 37 | obj->Thrd->Join(); 38 | sys::Print(obj->Fld + " : " + string(clock())); 39 | //} 40 | -------------------------------------------------------------------------------- /tests/customPackageTest.rct: -------------------------------------------------------------------------------- 1 | package sys 2 | 3 | class TestClass { 4 | set string FieldOne; 5 | set int FieldTwo; 6 | } 7 | 8 | function PrintString(someString string) { 9 | sys::Print("a"); 10 | } -------------------------------------------------------------------------------- /tests/dicTest.rct: -------------------------------------------------------------------------------- 1 | package sys; 2 | package Dictionary; 3 | 4 | var dict <- make Dictionary::Dictionary(); 5 | dict->Set("elem1", 100); 6 | dict->Set("elem1", 200.30); 7 | dict->Set("elem3", "a"); 8 | 9 | sys::Print(string(dict->Get("elem3"))); 10 | //sys::Print(string(float(dict->Get("elem2")))); 11 | sys::Print(string(int(dict->Get("elem1")))); -------------------------------------------------------------------------------- /tests/exceptionTest.rct: -------------------------------------------------------------------------------- 1 | package sys; 2 | 3 | var num <- 1 4 | var obj <- any(num); 5 | var str <- array[string](obj); 6 | 7 | sys::Print(str[0]); 8 | 9 | //var newStr <- str->Substring(-1, 10); -------------------------------------------------------------------------------- /tests/fib.rct: -------------------------------------------------------------------------------- 1 | package sys; 2 | var start <- sys::Now(); 3 | 4 | function fib(n long) long { 5 | if (n <= 1) return n; 6 | return fib(n - 1) + fib(n - 2); 7 | } 8 | 9 | sys::Print(string(fib(47))); 10 | var end <- sys::Now(); 11 | 12 | sys::Print(string((end - start) / 1000) + "ms"); -------------------------------------------------------------------------------- /tests/helloWorld.rct: -------------------------------------------------------------------------------- 1 | package sys; 2 | 3 | function main_impostor() { 4 | var index <- 0; 5 | 6 | while (true) { 7 | sys::Print("Hello, world! #" + string(index)); 8 | index++; 9 | } 10 | } 11 | 12 | main_impostor(); -------------------------------------------------------------------------------- /tests/konsoleTest.rct: -------------------------------------------------------------------------------- 1 | package sys; 2 | package konsole; 3 | 4 | Header("Indexed foreground color:"); 5 | 6 | from (i <- 0) to 15 { 7 | konsole::SetFgInt(i); 8 | konsole::WriteAndReset(string("#")) 9 | } 10 | 11 | Header("\n\nIndexed background color:"); 12 | 13 | from (i <- 0) to 15 { 14 | konsole::SetBgInt(i); 15 | konsole::WriteAndReset(string("#")) 16 | } 17 | 18 | Header("\n\nIndexed foreground and background colors:"); 19 | 20 | from (i <- 0) to 15 { 21 | konsole::SetFgInt(i); 22 | konsole::SetBgInt(i); 23 | konsole::WriteAndReset(string(" ")) 24 | } 25 | 26 | Header("\n\nRGB:"); 27 | 28 | from (y <- 0) to 10 { 29 | from (x <- 0) to 10 { 30 | konsole::SetBgRGB(int(25.5 * y), int(25.5 * x), 255 - int(25.5 * x)); 31 | konsole::WriteAndReset(string(" ")) 32 | } 33 | sys::Print(""); 34 | } 35 | 36 | Header("\n\nHex:"); 37 | konsole::SetBgCol(0xff6666); 38 | konsole::PrintAndReset(string("This is 0xff6666")) 39 | 40 | Header("\n\nOther formatting things:"); 41 | 42 | konsole::Bold(); 43 | konsole::PrintAndReset("Bold"); 44 | 45 | konsole::Italic(); 46 | konsole::PrintAndReset("Italic"); 47 | 48 | konsole::Underline(); 49 | konsole::PrintAndReset("Underline"); 50 | 51 | konsole::CrossedOut(); 52 | konsole::PrintAndReset("CrossedOut"); 53 | 54 | Header("\n\n" + konsole::GetGradient("GRADIENTS", false, 168, 50, 50, 168, 111, 50)); 55 | 56 | konsole::PrintGradient("This is a gradient.", 0, 0, 0, 255, 255, 255); 57 | konsole::PrintBgGradient("This is a gradient.", 0, 0, 0, 255, 255, 255); 58 | konsole::WriteBgGradient(" ", "This text is very colorful", 50, 168, 84, 50, 144, 168 ); 59 | konsole::PrintBgGradient(" ", 50, 168, 84, 50, 144, 168); 60 | 61 | function Header(text string) { 62 | konsole::Bold(); 63 | konsole::Underline(); 64 | konsole::PrintAndReset(text); 65 | } -------------------------------------------------------------------------------- /tests/lambda.rct: -------------------------------------------------------------------------------- 1 | package sys; 2 | 3 | // lambda notation 4 | // --------------- 5 | 6 | var action[int,int,int] avg; 7 | // | | | 8 | // | | +-> last = return type 9 | // | +-> parameter b 10 | // +-> parameter a 11 | 12 | avg <- lambda(a int, b int) int { 13 | sys::Print("big brain calculation going on here"); 14 | return (a + b) / 2; 15 | }; 16 | 17 | sys::Print(string( 18 | avg->Run(0, 50) // runnin the gamer 19 | )); 20 | 21 | // using functions like lambdas 22 | // ---------------------------- 23 | 24 | function Sum(a int, b int) int { 25 | return a + b; 26 | } 27 | 28 | var sum <- Sum; // sum now has the type of action[int, int, int] 29 | 30 | sys::Print(string( 31 | sum->Run(2,5) // runnin the other gamer 32 | )); 33 | 34 | -------------------------------------------------------------------------------- /tests/lowlevelrect.rct: -------------------------------------------------------------------------------- 1 | // ============================================================================ 2 | // no sys package here (lies) 3 | package sys; 4 | // but a sneaky external function 5 | external puts(str pointer[byte]) int; 6 | external putchar(chr int) int; 7 | // ============================================================================ 8 | 9 | while (true) { 10 | sys::Print(string("we gamin"->GetLength())); 11 | break 12 | } 13 | //Print("we gamin"); 14 | //Print("we chillin"); 15 | 16 | function Print(msg string) { 17 | //puts(msg->GetBuffer()); 18 | for (var p <- msg->GetBuffer(); deref p != 0; p++) { 19 | putchar(deref p); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /tests/multifile/one.rct: -------------------------------------------------------------------------------- 1 | // one.rct 2 | package sys; 3 | 4 | #source("./tests/multifile/two.rct"); 5 | 6 | deez(); 7 | 8 | function deez() { 9 | sys::Write("deez "); 10 | nutz(); 11 | } -------------------------------------------------------------------------------- /tests/multifile/two.rct: -------------------------------------------------------------------------------- 1 | // two.rct 2 | function nutz() { 3 | sys::Print("nutz."); 4 | } -------------------------------------------------------------------------------- /tests/packageTest.rct: -------------------------------------------------------------------------------- 1 | package test 2 | //Print(test::GetString()); 3 | 4 | while (true) { 5 | // create an instance of the package class 6 | var thing <- make test::Thing("this is such input"); 7 | thing->Output(); 8 | 9 | // check if casting works 10 | var someAny <- any(thing); 11 | var thingAgain <- test::Thing(someAny); 12 | 13 | // check if field access works 14 | Print(thingAgain->someString + " #2"); 15 | 16 | // check if field assignment works 17 | thingAgain->someString <- "much string"; 18 | thingAgain->Output(); 19 | 20 | // check if arrays of the class can be created 21 | var thingArray <- make test::Thing array(1); 22 | thingArray[0] <- thing; 23 | 24 | // check if array expansion works 25 | thingArray->Push(make test::Thing("cool beans")); 26 | 27 | // check if indexing works correctly 28 | from (i <- 0) to thingArray->GetLength() - 1 { 29 | thingArray[i]->Output(); 30 | } 31 | 32 | // check if passing arrays works 33 | var strArr <- make string array { "string 1", "string 2" }; 34 | strArr->Push("sussy"); 35 | strArr->Push("baka"); 36 | 37 | test::PrintArr(strArr); 38 | 39 | // check if getting an array from a package works 40 | var newArr <- test::GetStringArray("my string", 10); 41 | from (i <- 0) to newArr->GetLength() -1 { 42 | Print(string(i) + ": " + newArr[i]) 43 | } 44 | 45 | // check if getting a 2d array from a package works 46 | var nestedArr <- test::Get2DStringArray("a", 3, 3); 47 | from (x <- 0) to nestedArr->GetLength() -1 { 48 | from (y <- 0) to nestedArr->GetLength() -1 { 49 | Write(nestedArr[x][y] + ", "); 50 | } 51 | Print(""); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /tests/preproc.rct: -------------------------------------------------------------------------------- 1 | #attach("./tests/multifile/one.rct"); -------------------------------------------------------------------------------- /tests/primeBenchmark.rct: -------------------------------------------------------------------------------- 1 | var start <- Now(); 2 | 3 | // to what number we want to get all primes 4 | set primesUpTo <- 10_000_000; 5 | 6 | // no numbers are ruled out at the beginning 7 | var ruledOut <- make bool array(primesUpTo); 8 | 9 | // rule out 0 and 1 10 | ruledOut[0] <- true; 11 | ruledOut[1] <- true; 12 | 13 | // the biggest prime factor will be less than the square root of our max value 14 | from (i <- 0) to Sqrt(primesUpTo) 15 | { 16 | if (!ruledOut[i]) 17 | { 18 | // i is a prime number! 19 | // rule out all of its multiples 20 | for (var j <- i * i; j < primesUpTo; j <-+ i) 21 | ruledOut[j] <- true; 22 | } 23 | } 24 | 25 | // our prime array 26 | var primes <- make int array(0); 27 | 28 | // collect all our primes 29 | from (i <- 0) to primesUpTo - 1 { 30 | if (!ruledOut[i]) 31 | { 32 | primes->Push(i); 33 | } 34 | } 35 | 36 | var end <- Now(); 37 | var mills <- (end - start) / 1000; 38 | 39 | Print("FOUND PRIMES: " + string(primes->GetLength())); 40 | Print("TOOK: " + string(mills) + "ms (~"+string(mills / 1000)+"s)"); -------------------------------------------------------------------------------- /tests/stringBenchmark.rct: -------------------------------------------------------------------------------- 1 | var start <- Now(); 2 | 3 | // number of cycles we are going to do 4 | set cycles <- 100_000; 5 | 6 | // string pointer 7 | set stringPointer <- 0; 8 | 9 | // a set of strings we can use 10 | set stringSet <- make string array(5); 11 | stringSet[0] <- "aaaaa"; 12 | stringSet[1] <- "bbbbb"; 13 | stringSet[2] <- "ccccc"; 14 | stringSet[3] <- "ddddd"; 15 | stringSet[4] <- "eeeee"; 16 | 17 | // our string array 18 | var strings <- make string array(0); 19 | strings->Push(GetString()); 20 | 21 | // the biggest prime factor will be less than the square root of our max value 22 | from (i <- 0) to cycles 23 | { 24 | // add a new elements that is the last elements end + a new string from our set 25 | var last <- strings[strings->GetLength() - 1]; 26 | strings->Push(last->Substring(last->GetLength() - 5, 5) + GetString()); 27 | } 28 | 29 | from (i <- 0) to strings->GetLength() -1 30 | Print(strings[i]); 31 | 32 | 33 | var end <- Now(); 34 | var mills <- (end - start) / 1000; 35 | 36 | 37 | Print("CYCLES: " + string(cycles)); 38 | Print("TOOK: " + string(mills) + "ms (~"+string(mills / 1000)+"s)"); 39 | 40 | function GetString() string 41 | { 42 | var str <- stringSet[stringPointer]; 43 | 44 | stringPointer++; 45 | if (stringPointer >= stringSet->GetLength()) stringPointer <- 0; 46 | 47 | return str; 48 | } -------------------------------------------------------------------------------- /tests/sysTest.rct: -------------------------------------------------------------------------------- 1 | package sus; // we crashin 2 | alias sys sus; 3 | 4 | sys::Print("i wanna die"); 5 | someFunc(); 6 | 7 | function someFunc() void { 8 | sus::Print("hmm"); 9 | } 10 | -------------------------------------------------------------------------------- /tests/test1.rct: -------------------------------------------------------------------------------- 1 | var name <- "Jerry"; 2 | set age <- 11409830; 3 | var alive <- tr$ue; // supposed to fail btw 4 | 5 | if(alive) { 6 | Print("Jerry is alive") 7 | } else { 8 | Print("Oh no! Jerry is dead!") 9 | } -------------------------------------------------------------------------------- /tests/threadTest.rct: -------------------------------------------------------------------------------- 1 | package sys; 2 | 3 | var thrd <- ( 4 | lambda (someString string) { 5 | //sys::Print("Got the string: " + someString); 6 | //sys::Print("very cool"); 7 | while (true) { 8 | sys::Write(someString); 9 | } 10 | } 11 | )->RunThread("among us"); 12 | 13 | 14 | sys::Print("we threadin :)"); 15 | //thrd->Join(); // wait for the thread to conclude 16 | //sys::Print("no more thread :("); 17 | 18 | sys::Sleep(4000); 19 | 20 | thrd->Kill(); 21 | sys::Print("no more thread >:)"); 22 | -------------------------------------------------------------------------------- /tests/wedoalittlemeta.rct: -------------------------------------------------------------------------------- 1 | package sys; 2 | 3 | struct struct_String { 4 | vTable pointer[byte], 5 | refCount int, 6 | buffer pointer[byte], 7 | length int, 8 | maxLen int, 9 | factor int 10 | } 11 | 12 | external malloc(size int) pointer[byte]; 13 | external free(ptr pointer[byte]); 14 | external String_public_Constructor(this pointer[struct_String]); 15 | external String_public_Load(this pointer[struct_String], chars pointer[byte]); 16 | //external String_public_Die(); 17 | external arc_RegisterReference(obj pointer[byte]); 18 | 19 | var pointer[struct_String] str <- pointer[struct_String](malloc(30)); // no clue how large this struct is 20 | 21 | // mak strg 22 | String_public_Constructor(str); 23 | String_public_Load(str, 'sussy baka'); 24 | 25 | // register reference 26 | arc_RegisterReference(pointer[byte](str)); 27 | 28 | // print 29 | sys::Print(string(str)); --------------------------------------------------------------------------------