From f96414eb98cff8f488f7183b2dc28d073df581bd Mon Sep 17 00:00:00 2001 From: Antonio Date: Tue, 23 Aug 2022 14:37:49 -0500 Subject: [PATCH 1/4] First adoption attemp of plasma 1.0.1 --- config.go | 12 +- docs/scripting.md | 20 +- driver.go | 408 ++++++++++++++++++-------------- go.mod | 3 +- go.sum | 2 + sample-config/scripts/auth.pm | 2 +- sample-config/scripts/filter.pm | 8 +- 7 files changed, 261 insertions(+), 194 deletions(-) diff --git a/config.go b/config.go index 58d8f5f..1547fcb 100644 --- a/config.go +++ b/config.go @@ -234,16 +234,16 @@ func (r *runner) loadSniffers(incoming, outgoing string) (i io.WriteCloser, o io func (r *runner) loadFilters(filters Filters) listeners.Filters { listenerFilter := &filter{} if f, found := r.drivers[filters.Inbound]; found { - listenerFilter.inbound = f.inbound + listenerFilter.inbound = f.Inbound } if f, found := r.drivers[filters.Outbound]; found { - listenerFilter.outbound = f.outbound + listenerFilter.outbound = f.Outbound } if f, found := r.drivers[filters.Listen]; found { - listenerFilter.listen = f.listen + listenerFilter.listen = f.Listen } if f, found := r.drivers[filters.Accept]; found { - listenerFilter.accept = f.accept + listenerFilter.accept = f.Accept } return listenerFilter } @@ -338,8 +338,8 @@ func (r *runner) startConfig(c YAML) { ) log.Print("Loading drivers") r.drivers = map[string]*Driver{} - for name, script := range c.Drivers { - r.drivers[name], err = loadDriver(script) + for name, scriptCode := range c.Drivers { + r.drivers[name], err = r.loadDriver(scriptCode) if err != nil { printAndExit(err.Error(), 1) } diff --git a/docs/scripting.md b/docs/scripting.md index e446592..c1fbfaf 100644 --- a/docs/scripting.md +++ b/docs/scripting.md @@ -4,7 +4,7 @@ This document describe the interfaces used in `fullproxy` driver development. ## Authentication functions -Functions intended for authentication will be loaded using `SetAuth(function)`, functions should expect two string +Functions intended for authentication will be loaded using `set_auth(function)`, functions should expect two string arguments, specifically corresponding to username and password, authentication succeed will be evaluated by the return values `True` in case of success or `False` in case of failure, notice if the function call raises an error it will be also considered an auth failure. @@ -19,17 +19,17 @@ def basic_login(username, password) return False end -SetAuth(basic_login) +set_auth(basic_login) ``` ## Filtering functions Function intended to filter incoming, outgoing, listens and accepts can be loaded in drivers using: -- `SetInbound(function)` -- `SetOutbound(function)` -- `SetListen(function)` -- `SetAccept(function)` +- `set_inbound(function)` +- `set_outbound(function)` +- `set_listen(function)` +- `set_accept(function)` This functions are expected to receive a string value containing the `HOST:PORT` value of the connection. Allowing the connection will be evaluated by the return values `True` in case of success or `False` in case of failure, notice if the @@ -47,8 +47,8 @@ def no_localhost(address) return True end -SetInbound(no_localhost) -SetOutbound(no_localhost) -SetListen(no_localhost) -SetAccept(no_localhost) +set_inbound(no_localhost) +set_outbound(no_localhost) +set_listen(no_localhost) +set_accept(no_localhost) ``` diff --git a/driver.go b/driver.go index 699d7ea..4c3a355 100644 --- a/driver.go +++ b/driver.go @@ -2,10 +2,10 @@ package main import ( "errors" - "github.com/shoriwe/gplasma" + "github.com/shoriwe/gplasma/pkg/ast3" + "github.com/shoriwe/gplasma/pkg/bytecode/assembler" "github.com/shoriwe/gplasma/pkg/vm" "os" - "sync" ) var ( @@ -16,6 +16,124 @@ var ( permissionDeniedAccept = errors.New("permission denied for accepted client") ) +func authScript(username, password []byte) []byte { + bytecode, _ := assembler.Assemble( + ast3.Program{ + ast3.Call{ + Function: &ast3.Selector{ + X: &ast3.Identifier{ + Symbol: "-driver", + }, + Identifier: &ast3.Identifier{ + Symbol: "-auth", + }, + }, + Arguments: []ast3.Expression{ + &ast3.String{ + Contents: username, + }, + &ast3.String{ + Contents: password, + }, + }, + }, + }, + ) + return bytecode +} + +func inboundScript(address []byte) []byte { + bytecode, _ := assembler.Assemble( + ast3.Program{ + ast3.Call{ + Function: &ast3.Selector{ + X: &ast3.Identifier{ + Symbol: "-driver", + }, + Identifier: &ast3.Identifier{ + Symbol: "-inbound", + }, + }, + Arguments: []ast3.Expression{ + &ast3.String{ + Contents: address, + }, + }, + }, + }, + ) + return bytecode +} + +func outboundScript(address []byte) []byte { + bytecode, _ := assembler.Assemble( + ast3.Program{ + ast3.Call{ + Function: &ast3.Selector{ + X: &ast3.Identifier{ + Symbol: "-driver", + }, + Identifier: &ast3.Identifier{ + Symbol: "-outbound", + }, + }, + Arguments: []ast3.Expression{ + &ast3.String{ + Contents: address, + }, + }, + }, + }, + ) + return bytecode +} + +func listenScript(address []byte) []byte { + bytecode, _ := assembler.Assemble( + ast3.Program{ + ast3.Call{ + Function: &ast3.Selector{ + X: &ast3.Identifier{ + Symbol: "-driver", + }, + Identifier: &ast3.Identifier{ + Symbol: "-listen", + }, + }, + Arguments: []ast3.Expression{ + &ast3.String{ + Contents: address, + }, + }, + }, + }, + ) + return bytecode +} + +func acceptScript(address []byte) []byte { + bytecode, _ := assembler.Assemble( + ast3.Program{ + ast3.Call{ + Function: &ast3.Selector{ + X: &ast3.Identifier{ + Symbol: "-driver", + }, + Identifier: &ast3.Identifier{ + Symbol: "-accept", + }, + }, + Arguments: []ast3.Expression{ + &ast3.String{ + Contents: address, + }, + }, + }, + }, + ) + return bytecode +} + type filter struct { inbound func(string) error outbound func(string) error @@ -52,204 +170,150 @@ func (f *filter) Accept(address string) error { } type Driver struct { - mutex *sync.Mutex - auth func(string, string) error - inbound func(string) error - outbound func(string) error - listen func(string) error - accept func(string) error + plasma *vm.Plasma } func (d *Driver) Auth(username, password []byte) error { - if d.auth == nil { - return nil + bytecode := authScript(username, password) + resultChannel, errorChannel, _ := d.plasma.Execute(bytecode) + if err := <-errorChannel; err != nil { + return err + } + result := <-resultChannel + if !result.Bool() { + return authenticationFailed } - return d.auth(string(username), string(password)) + return nil } func (d *Driver) Inbound(address string) error { - if d.inbound == nil { - return nil + bytecode := inboundScript([]byte(address)) + resultChannel, errorChannel, _ := d.plasma.Execute(bytecode) + if err := <-errorChannel; err != nil { + return err + } + result := <-resultChannel + if !result.Bool() { + return permissionDeniedInbound } - return d.inbound(address) + return nil } func (d *Driver) Outbound(address string) error { - if d.outbound == nil { - return nil + bytecode := outboundScript([]byte(address)) + resultChannel, errorChannel, _ := d.plasma.Execute(bytecode) + if err := <-errorChannel; err != nil { + return err + } + result := <-resultChannel + if !result.Bool() { + return permissionDeniedOutbound } - return d.outbound(address) + return nil } func (d *Driver) Listen(address string) error { - if d.listen == nil { - return nil + bytecode := listenScript([]byte(address)) + resultChannel, errorChannel, _ := d.plasma.Execute(bytecode) + if err := <-errorChannel; err != nil { + return err + } + result := <-resultChannel + if !result.Bool() { + return permissionDeniedListen } - return d.listen(address) + return nil } func (d *Driver) Accept(address string) error { - if d.accept == nil { - return nil + bytecode := acceptScript([]byte(address)) + resultChannel, errorChannel, _ := d.plasma.Execute(bytecode) + if err := <-errorChannel; err != nil { + return err + } + result := <-resultChannel + if !result.Bool() { + return permissionDeniedAccept + } + return nil +} + +func (r *runner) loadDriver(script string) (*Driver, error) { + d := &Driver{ + plasma: initializeVM(), } - return d.accept(address) -} - -func interpretAsString(v *vm.Value, ctx *vm.Context, p *vm.Plasma) string { - if v.IsTypeById(vm.StringId) { - return v.String - } - toString, getToStringException := v.Get(p, ctx, "ToString") - if getToStringException != nil { - return "Failed to get ToString of object" - } - result, succeed := p.CallFunction(ctx, toString) - if !succeed { - return "Failed to call ToString" - } - return result.String -} - -func (d *Driver) feature() vm.Feature { - return vm.Feature{ - "SetAuth": func(context *vm.Context, plasma *vm.Plasma) *vm.Value { - return plasma.NewFunction( - context, true, context.PeekSymbolTable(), - vm.NewBuiltInFunction(1, - func(self *vm.Value, arguments ...*vm.Value) (*vm.Value, bool) { - d.auth = func(username string, password string) error { - d.mutex.Lock() - defer d.mutex.Unlock() - result, succeed := plasma.CallFunction(context, arguments[0], - plasma.NewString(context, false, username), - plasma.NewString(context, false, password), - ) - if !succeed { - return errors.New(interpretAsString(result, context, plasma)) - } - if result.Bool { - return nil - } - return authenticationFailed - } - return plasma.GetNone(), true - }, - ), + // Setup the names used by the script + _, errorChannel, _ := d.plasma.ExecuteString(script) + // + + if err := <-errorChannel; err != nil { + return nil, errors.New("driver script execution error") + } + return d, nil +} + +func initializeVM() *vm.Plasma { + plasma := vm.NewVM(os.Stdin, os.Stdout, os.Stderr) + plasma.Load("-driver", func(_ *vm.Plasma) *vm.Value { return plasma.None() }) + plasma.Load("set_auth", + func(p *vm.Plasma) *vm.Value { + return p.NewBuiltInFunction( + p.Symbols(), + func(argument ...*vm.Value) (*vm.Value, error) { + driver, _ := p.Symbols().Get("-driver") + driver.Set("-auth", argument[0]) + return p.None(), nil + }, ) }, - "SetInbound": func(context *vm.Context, plasma *vm.Plasma) *vm.Value { - return plasma.NewFunction( - context, true, context.PeekSymbolTable(), - vm.NewBuiltInFunction(1, - func(self *vm.Value, arguments ...*vm.Value) (*vm.Value, bool) { - d.inbound = func(address string) error { - d.mutex.Lock() - defer d.mutex.Unlock() - result, succeed := plasma.CallFunction(context, arguments[0], - plasma.NewString(context, false, address), - ) - if !succeed { - return errors.New(interpretAsString(result, context, plasma)) - } - if result.Bool { - return nil - } - return permissionDeniedInbound - } - return plasma.GetNone(), true - }, - ), + ) + plasma.Load("set_inbound", + func(p *vm.Plasma) *vm.Value { + return p.NewBuiltInFunction( + p.Symbols(), + func(argument ...*vm.Value) (*vm.Value, error) { + driver, _ := p.Symbols().Get("-driver") + driver.Set("-inbound", argument[0]) + return p.None(), nil + }, ) }, - "SetOutbound": func(context *vm.Context, plasma *vm.Plasma) *vm.Value { - return plasma.NewFunction( - context, true, context.PeekSymbolTable(), - vm.NewBuiltInFunction(1, - func(self *vm.Value, arguments ...*vm.Value) (*vm.Value, bool) { - d.outbound = func(address string) error { - d.mutex.Lock() - defer d.mutex.Unlock() - result, succeed := plasma.CallFunction(context, arguments[0], - plasma.NewString(context, false, address), - ) - if !succeed { - return errors.New(interpretAsString(result, context, plasma)) - } - if result.Bool { - return nil - } - return permissionDeniedOutbound - } - return plasma.GetNone(), true - }, - ), + ) + plasma.Load("set_outbound", + func(p *vm.Plasma) *vm.Value { + return p.NewBuiltInFunction( + p.Symbols(), + func(argument ...*vm.Value) (*vm.Value, error) { + driver, _ := p.Symbols().Get("-driver") + driver.Set("-outbound", argument[0]) + return p.None(), nil + }, ) }, - "SetListen": func(context *vm.Context, plasma *vm.Plasma) *vm.Value { - return plasma.NewFunction( - context, true, context.PeekSymbolTable(), - vm.NewBuiltInFunction(1, - func(self *vm.Value, arguments ...*vm.Value) (*vm.Value, bool) { - d.listen = func(address string) error { - d.mutex.Lock() - defer d.mutex.Unlock() - result, succeed := plasma.CallFunction(context, arguments[0], - plasma.NewString(context, false, address), - ) - if !succeed { - return errors.New(interpretAsString(result, context, plasma)) - } - if result.Bool { - return nil - } - return permissionDeniedListen - } - return plasma.GetNone(), true - }, - ), + ) + plasma.Load("set_listen", + func(p *vm.Plasma) *vm.Value { + return p.NewBuiltInFunction( + p.Symbols(), + func(argument ...*vm.Value) (*vm.Value, error) { + driver, _ := p.Symbols().Get("-driver") + driver.Set("-listen", argument[0]) + return p.None(), nil + }, ) }, - "SetAccept": func(context *vm.Context, plasma *vm.Plasma) *vm.Value { - return plasma.NewFunction( - context, true, context.PeekSymbolTable(), - vm.NewBuiltInFunction(1, - func(self *vm.Value, arguments ...*vm.Value) (*vm.Value, bool) { - d.accept = func(address string) error { - d.mutex.Lock() - defer d.mutex.Unlock() - result, succeed := plasma.CallFunction(context, arguments[0], - plasma.NewString(context, false, address), - ) - if !succeed { - return errors.New(interpretAsString(result, context, plasma)) - } - if result.Bool { - return nil - } - return permissionDeniedAccept - } - return plasma.GetNone(), true - }, - ), + ) + plasma.Load("set_accept", + func(p *vm.Plasma) *vm.Value { + return p.NewBuiltInFunction( + p.Symbols(), + func(argument ...*vm.Value) (*vm.Value, error) { + driver, _ := p.Symbols().Get("-driver") + driver.Set("-accept", argument[0]) + return p.None(), nil + }, ) }, - } -} - -func loadDriver(script string) (*Driver, error) { - d := &Driver{ - mutex: &sync.Mutex{}, - } - v := gplasma.NewVirtualMachine() - v.LoadFeature(d.feature()) - - scriptContents, readError := os.ReadFile(script) - if readError != nil { - return nil, readError - } - _, succeed := v.ExecuteMain(string(scriptContents)) - if !succeed { - return nil, errors.New("driver script execution error") - } - return d, nil + ) + return plasma } diff --git a/go.mod b/go.mod index 5fc2e55..c56a578 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,8 @@ go 1.16 require ( github.com/elazarl/goproxy v0.0.0-20210801061803-8e322dfb79c4 // indirect github.com/gorilla/websocket v1.5.0 // indirect - github.com/shoriwe/gplasma v0.0.0-20220517214355-8a4aa6af9004 // indirect + github.com/otiai10/copy v1.6.0 // indirect + github.com/shoriwe/gplasma v1.0.1 // indirect golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 golang.org/x/net v0.0.0-20210908191846-a5e095526f91 gopkg.in/elazarl/goproxy.v1 v1.0.0-20180725130230-947c36da3153 diff --git a/go.sum b/go.sum index e823405..814359a 100644 --- a/go.sum +++ b/go.sum @@ -17,6 +17,8 @@ github.com/shoriwe/gplasma v0.0.0-20211103070337-347bfcd57a67 h1:T2K23Kb62Q6LXxH github.com/shoriwe/gplasma v0.0.0-20211103070337-347bfcd57a67/go.mod h1:4Wd1xurUfcdcoJVhu++BCj4N8bfCp1hwlR+TEmqz6TA= github.com/shoriwe/gplasma v0.0.0-20220517214355-8a4aa6af9004 h1:k07yeLPKhs7zLueZJLfLwPlVkiDchxAg5Y/SDErXJM8= github.com/shoriwe/gplasma v0.0.0-20220517214355-8a4aa6af9004/go.mod h1:4Wd1xurUfcdcoJVhu++BCj4N8bfCp1hwlR+TEmqz6TA= +github.com/shoriwe/gplasma v1.0.1 h1:q4peogYDCTSWrSKWNP8+OLvmDWMdEeS7wsT3hF69EOc= +github.com/shoriwe/gplasma v1.0.1/go.mod h1:f9gs3jQQMWvY+XCbKe1oB7xpiJSuU5FjKQvP9aNs2Ko= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= diff --git a/sample-config/scripts/auth.pm b/sample-config/scripts/auth.pm index c176448..6e16b58 100644 --- a/sample-config/scripts/auth.pm +++ b/sample-config/scripts/auth.pm @@ -5,4 +5,4 @@ def basic_login(username, password) return False end -SetAuth(basic_login) \ No newline at end of file +set_auth(basic_login) \ No newline at end of file diff --git a/sample-config/scripts/filter.pm b/sample-config/scripts/filter.pm index 777512c..e500b2f 100644 --- a/sample-config/scripts/filter.pm +++ b/sample-config/scripts/filter.pm @@ -7,7 +7,7 @@ def no_localhost(address) return True end -SetInbound(no_localhost) -SetOutbound(no_localhost) -SetListen(no_localhost) -SetAccept(no_localhost) \ No newline at end of file +set_inbound(no_localhost) +set_outbound(no_localhost) +set_listen(no_localhost) +set_accept(no_localhost) \ No newline at end of file From 84d80612ed2e0c93edcdc6bb4cbac3873db3d17c Mon Sep 17 00:00:00 2001 From: Antonio Date: Tue, 23 Aug 2022 14:38:01 -0500 Subject: [PATCH 2/4] Updated vendor dependencies --- .../github.com/shoriwe/gplasma/.gitattributes | 2 - vendor/github.com/shoriwe/gplasma/.gitignore | 1 - vendor/github.com/shoriwe/gplasma/README.md | 142 - vendor/github.com/shoriwe/gplasma/ToDo.md | 95 - .../github.com/shoriwe/gplasma/count-lines.py | 19 - vendor/github.com/shoriwe/gplasma/go.mod | 8 - vendor/github.com/shoriwe/gplasma/go.sum | 15 - .../gplasma/pkg/{compiler => }/ast/ToDo.md | 0 .../shoriwe/gplasma/pkg/ast/expression.go | 112 + .../shoriwe/gplasma/pkg/ast/node.go | 14 + .../shoriwe/gplasma/pkg/ast/statement.go | 153 + .../shoriwe/gplasma/pkg/ast/walk.go | 200 ++ .../shoriwe/gplasma/pkg/ast2/expression.go | 156 ++ .../shoriwe/gplasma/pkg/ast2/node.go | 8 + .../shoriwe/gplasma/pkg/ast2/statement.go | 81 + .../shoriwe/gplasma/pkg/ast3/expression.go | 100 + .../shoriwe/gplasma/pkg/ast3/node.go | 8 + .../shoriwe/gplasma/pkg/ast3/statement.go | 42 + .../pkg/bytecode/assembler/assemble-array.go | 18 + .../bytecode/assembler/assemble-assignment.go | 40 + .../pkg/bytecode/assembler/assemble-call.go | 20 + .../pkg/bytecode/assembler/assemble-class.go | 26 + .../pkg/bytecode/assembler/assemble-defer.go | 15 + .../pkg/bytecode/assembler/assemble-delete.go | 41 + .../bytecode/assembler/assemble-expression.go | 51 + .../bytecode/assembler/assemble-function.go | 26 + .../pkg/bytecode/assembler/assemble-hash.go | 20 + .../bytecode/assembler/assemble-identifier.go | 15 + .../pkg/bytecode/assembler/assemble-index.go | 21 + .../pkg/bytecode/assembler/assemble-jump.go | 32 + .../pkg/bytecode/assembler/assemble-label.go | 13 + .../bytecode/assembler/assemble-literals.go | 49 + .../assembler/assemble-return-yield.go | 18 + .../bytecode/assembler/assemble-selector.go | 17 + .../bytecode/assembler/assemble-statement.go | 34 + .../pkg/bytecode/assembler/assemble-super.go | 14 + .../pkg/bytecode/assembler/assemble-tuple.go | 18 + .../pkg/bytecode/assembler/assemble.go | 275 ++ .../gplasma/pkg/bytecode/opcodes/opcodes.go | 61 + .../shoriwe/gplasma/pkg/common/list-stack.go | 32 + .../pkg/common/magic-functions/array.go | 9 + .../gplasma/pkg/common/magic-functions/int.go | 8 + .../common/magic-functions/magic-functions.go | 51 + .../pkg/common/magic-functions/string.go | 10 + .../shoriwe/gplasma/pkg/common/map.go | 13 + .../shoriwe/gplasma/pkg/common/numeric.go | 47 + .../common/special-symbols/special-symbols.go | 21 + .../gplasma/pkg/compiler/ast/expression.go | 663 ----- .../shoriwe/gplasma/pkg/compiler/ast/node.go | 54 - .../gplasma/pkg/compiler/ast/statement.go | 772 ----- .../shoriwe/gplasma/pkg/compiler/compile.go | 42 + .../gplasma/pkg/compiler/lexer/lexer.go | 629 ----- .../gplasma/pkg/compiler/parser/parser.go | 2477 ----------------- .../shoriwe/gplasma/pkg/errors/error.go | 47 - .../gplasma/pkg/errors/runtime_errors.go | 40 - .../gplasma/pkg/{compiler => }/lexer/ToDo.md | 2 +- .../shoriwe/gplasma/pkg/lexer/detect-kind.go | 90 + .../shoriwe/gplasma/pkg/lexer/kinds.go | 25 + .../shoriwe/gplasma/pkg/lexer/lexer.go | 234 ++ .../gplasma/pkg/{compiler => }/lexer/token.go | 140 +- .../gplasma/pkg/lexer/tokenize-binary.go | 33 + .../gplasma/pkg/lexer/tokenize-comment.go | 13 + .../gplasma/pkg/lexer/tokenize-float.go | 36 + .../shoriwe/gplasma/pkg/lexer/tokenize-hex.go | 38 + .../gplasma/pkg/lexer/tokenize-interger.go | 48 + .../gplasma/pkg/lexer/tokenize-numeric.go | 39 + .../gplasma/pkg/lexer/tokenize-octal.go | 33 + .../pkg/lexer/tokenize-repeatable-operator.go | 40 + .../pkg/lexer/tokenize-scientific-float.go | 47 + .../pkg/lexer/tokenize-single-operator.go | 19 + .../gplasma/pkg/lexer/tokenize-string.go | 49 + .../gplasma/pkg/lexer/tokenize-word.go | 13 + .../gplasma/pkg/{compiler => }/parser/ToDo.md | 0 .../shoriwe/gplasma/pkg/parser/common.go | 36 + .../shoriwe/gplasma/pkg/parser/errors.go | 47 + .../pkg/{compiler => }/parser/grammar.bnf | 0 .../shoriwe/gplasma/pkg/parser/iter.go | 21 + .../shoriwe/gplasma/pkg/parser/names.go | 43 + .../pkg/parser/parse-array-expression.go | 55 + .../pkg/parser/parse-assignment-statement.go | 30 + .../pkg/parser/parse-begin-statement.go | 46 + .../pkg/parser/parse-binary-expression.go | 53 + .../pkg/parser/parse-break-statement.go | 13 + .../pkg/parser/parse-class-statement.go | 105 + .../pkg/parser/parse-continue-statement.go | 13 + .../pkg/parser/parse-defer-statement.go | 20 + .../pkg/parser/parse-delete-statement.go | 20 + .../gplasma/pkg/parser/parse-do-while.go | 62 + .../gplasma/pkg/parser/parse-end-statement.go | 46 + .../gplasma/pkg/parser/parse-for-statement.go | 110 + .../parse-function-definition-statement.go | 126 + .../pkg/parser/parse-generator-expression.go | 88 + .../pkg/parser/parse-generator-statement.go | 126 + .../pkg/parser/parse-hash-expression.go | 86 + .../parser/parse-if-one-liner-expression.go | 53 + .../gplasma/pkg/parser/parse-if-statement.go | 141 + .../pkg/parser/parse-index-expression.go | 41 + .../pkg/parser/parse-interface-statement.go | 116 + .../pkg/parser/parse-lambda-expression.go | 71 + .../pkg/parser/parse-literal-expression.go | 32 + .../parse-method-invocation-expression.go | 55 + .../pkg/parser/parse-module-statement.go | 61 + .../gplasma/pkg/parser/parse-operand.go | 77 + .../parser/parse-parentheses-expression.go | 101 + .../pkg/parser/parse-pass-statement.go | 13 + .../pkg/parser/parse-return-statement.go | 43 + .../pkg/parser/parse-selector-expression.go | 34 + .../pkg/parser/parse-super-statement.go | 20 + .../pkg/parser/parse-switch-statement.go | 144 + .../pkg/parser/parse-unary-expression.go | 33 + .../parse-unless-one-liner-expression.go | 54 + .../pkg/parser/parse-unless-statement.go | 141 + .../pkg/parser/parse-until-statement.go | 61 + .../pkg/parser/parse-while-statement.go | 57 + .../pkg/parser/parse-yield-statement.go | 43 + .../pkg/parser/parser-primary-expression.go | 39 + .../shoriwe/gplasma/pkg/parser/parser.go | 78 + .../gplasma/pkg/passes/checks/checks.go | 125 + .../pkg/passes/checks/invalid-break.pm | 23 + .../pkg/passes/checks/invalid-continue.pm | 23 + .../pkg/passes/checks/invalid-return.pm | 26 + .../pkg/passes/checks/invalid-yield.pm | 23 + .../gplasma/pkg/passes/checks/valid-script.pm | 11 + .../passes/simplification/anon-identifier.go | 14 + .../passes/simplification/simplify-array.go | 16 + .../passes/simplification/simplify-assign.go | 107 + .../passes/simplification/simplify-binary.go | 69 + .../passes/simplification/simplify-call.go | 17 + .../passes/simplification/simplify-class.go | 22 + .../passes/simplification/simplify-defer.go | 12 + .../passes/simplification/simplify-delete.go | 23 + .../simplification/simplify-do-while.go | 20 + .../simplification/simplify-expression.go | 50 + .../pkg/passes/simplification/simplify-for.go | 75 + .../simplification/simplify-function.go | 22 + .../simplification/simplify-generator.go | 34 + .../passes/simplification/simplify-hash.go | 19 + .../simplification/simplify-identifier.go | 12 + .../simplification/simplify-if-one-liner.go | 25 + .../pkg/passes/simplification/simplify-if.go | 37 + .../passes/simplification/simplify-index.go | 13 + .../simplification/simplify-interface.go | 22 + .../passes/simplification/simplify-lambda.go | 17 + .../passes/simplification/simplify-literal.go | 196 ++ .../simplify-loop-operations.go | 14 + .../passes/simplification/simplify-module.go | 17 + .../simplification/simplify-parentheses.go | 10 + .../passes/simplification/simplify-pass.go | 10 + .../simplification/simplify-return-yield.go | 50 + .../simplification/simplify-selector.go | 13 + .../simplification/simplify-statement.go | 53 + .../passes/simplification/simplify-super.go | 12 + .../passes/simplification/simplify-switch.go | 59 + .../passes/simplification/simplify-tuple.go | 16 + .../passes/simplification/simplify-unary.go | 25 + .../passes/simplification/simplify-unless.go | 43 + .../passes/simplification/simplify-until.go | 23 + .../passes/simplification/simplify-while.go | 20 + .../pkg/passes/simplification/simplify.go | 64 + .../pkg/passes/transformations-1/label.go | 23 + .../transformations-1/transform-array.go | 16 + .../transformations-1/transform-assignment.go | 14 + .../transformations-1/transform-binary.go | 93 + .../transformations-1/transform-call.go | 17 + .../transformations-1/transform-class.go | 26 + .../transformations-1/transform-defer.go | 14 + .../transformations-1/transform-delete.go | 14 + .../transformations-1/transform-do-while.go | 36 + .../transformations-1/transform-expression.go | 55 + .../transformations-1/transform-function.go | 24 + .../transform-generator-expr.go | 121 + .../transformations-1/transform-generator.go | 429 +++ .../transformations-1/transform-hash.go | 19 + .../transformations-1/transform-identifier.go | 12 + .../transform-if-one-liner.go | 35 + .../passes/transformations-1/transform-if.go | 46 + .../transformations-1/transform-index.go | 13 + .../transformations-1/transform-lambda.go | 23 + .../transformations-1/transform-literals.go | 42 + .../transform-loop-operations.go | 18 + .../transformations-1/transform-module.go | 29 + .../transform-return-yield.go | 18 + .../transformations-1/transform-selector.go | 13 + .../transformations-1/transform-statement.go | 45 + .../transformations-1/transform-super.go | 12 + .../transformations-1/transform-tuple.go | 16 + .../transformations-1/transform-unary.go | 36 + .../transformations-1/transform-while.go | 47 + .../transformations-1/transformations.go | 49 + .../shoriwe/gplasma/pkg/reader/reader.go | 17 +- .../shoriwe/gplasma/pkg/tools/index.go | 17 - .../shoriwe/gplasma/pkg/tools/string.go | 75 - .../github.com/shoriwe/gplasma/pkg/vm/ToDo.md | 6 - .../shoriwe/gplasma/pkg/vm/array.go | 543 ++-- .../github.com/shoriwe/gplasma/pkg/vm/bool.go | 275 +- .../shoriwe/gplasma/pkg/vm/bytecode.go | 64 - .../shoriwe/gplasma/pkg/vm/bytes.go | 534 ++-- .../github.com/shoriwe/gplasma/pkg/vm/call.go | 174 -- .../shoriwe/gplasma/pkg/vm/class.go | 34 + .../shoriwe/gplasma/pkg/vm/config.go | 5 + .../shoriwe/gplasma/pkg/vm/constructor.go | 78 - .../shoriwe/gplasma/pkg/vm/context.go | 97 +- .../shoriwe/gplasma/pkg/vm/debug.go | 11 + .../shoriwe/gplasma/pkg/vm/default.go | 824 ------ .../github.com/shoriwe/gplasma/pkg/vm/do.go | 344 +++ .../shoriwe/gplasma/pkg/vm/error.go | 217 -- .../shoriwe/gplasma/pkg/vm/errors.go | 9 + .../shoriwe/gplasma/pkg/vm/execute.go | 196 -- .../shoriwe/gplasma/pkg/vm/float.go | 929 +++---- .../shoriwe/gplasma/pkg/vm/function.go | 24 +- .../shoriwe/gplasma/pkg/vm/function_names.go | 92 - .../shoriwe/gplasma/pkg/vm/hash-internal.go | 125 + .../github.com/shoriwe/gplasma/pkg/vm/hash.go | 84 + .../shoriwe/gplasma/pkg/vm/hashing.go | 7 - .../shoriwe/gplasma/pkg/vm/hashtable.go | 248 -- .../github.com/shoriwe/gplasma/pkg/vm/init.go | 248 ++ .../gplasma/pkg/vm/instruction_information.go | 45 - .../shoriwe/gplasma/pkg/vm/instructions.go | 722 ----- .../shoriwe/gplasma/pkg/vm/integer.go | 1252 +++------ .../shoriwe/gplasma/pkg/vm/iterator.go | 74 - .../shoriwe/gplasma/pkg/vm/module.go | 12 - .../github.com/shoriwe/gplasma/pkg/vm/none.go | 91 +- .../shoriwe/gplasma/pkg/vm/op_codes.go | 196 -- .../shoriwe/gplasma/pkg/vm/plasma.go | 150 - .../shoriwe/gplasma/pkg/vm/proxy_object.go | 20 - .../shoriwe/gplasma/pkg/vm/stack.go | 77 - .../shoriwe/gplasma/pkg/vm/string.go | 600 ++-- .../shoriwe/gplasma/pkg/vm/symbol-table.go | 65 + .../shoriwe/gplasma/pkg/vm/symbol_table.go | 39 - .../shoriwe/gplasma/pkg/vm/tools.go | 899 ------ .../shoriwe/gplasma/pkg/vm/tuple.go | 360 +-- .../github.com/shoriwe/gplasma/pkg/vm/type.go | 32 - .../shoriwe/gplasma/pkg/vm/type_names.go | 26 - .../shoriwe/gplasma/pkg/vm/value.go | 1051 ++++--- .../github.com/shoriwe/gplasma/pkg/vm/vm.go | 158 ++ vendor/github.com/shoriwe/gplasma/plasma.go | 60 - vendor/modules.txt | 24 +- 237 files changed, 11583 insertions(+), 12932 deletions(-) delete mode 100644 vendor/github.com/shoriwe/gplasma/.gitattributes delete mode 100644 vendor/github.com/shoriwe/gplasma/.gitignore delete mode 100644 vendor/github.com/shoriwe/gplasma/README.md delete mode 100644 vendor/github.com/shoriwe/gplasma/ToDo.md delete mode 100644 vendor/github.com/shoriwe/gplasma/count-lines.py delete mode 100644 vendor/github.com/shoriwe/gplasma/go.mod delete mode 100644 vendor/github.com/shoriwe/gplasma/go.sum rename vendor/github.com/shoriwe/gplasma/pkg/{compiler => }/ast/ToDo.md (100%) create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/ast/expression.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/ast/node.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/ast/statement.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/ast/walk.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/ast2/expression.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/ast2/node.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/ast2/statement.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/ast3/expression.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/ast3/node.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/ast3/statement.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-array.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-assignment.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-call.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-class.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-defer.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-delete.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-expression.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-function.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-hash.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-identifier.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-index.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-jump.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-label.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-literals.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-return-yield.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-selector.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-statement.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-super.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-tuple.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/bytecode/opcodes/opcodes.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/common/list-stack.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/common/magic-functions/array.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/common/magic-functions/int.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/common/magic-functions/magic-functions.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/common/magic-functions/string.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/common/map.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/common/numeric.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/common/special-symbols/special-symbols.go delete mode 100644 vendor/github.com/shoriwe/gplasma/pkg/compiler/ast/expression.go delete mode 100644 vendor/github.com/shoriwe/gplasma/pkg/compiler/ast/node.go delete mode 100644 vendor/github.com/shoriwe/gplasma/pkg/compiler/ast/statement.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/compiler/compile.go delete mode 100644 vendor/github.com/shoriwe/gplasma/pkg/compiler/lexer/lexer.go delete mode 100644 vendor/github.com/shoriwe/gplasma/pkg/compiler/parser/parser.go delete mode 100644 vendor/github.com/shoriwe/gplasma/pkg/errors/error.go delete mode 100644 vendor/github.com/shoriwe/gplasma/pkg/errors/runtime_errors.go rename vendor/github.com/shoriwe/gplasma/pkg/{compiler => }/lexer/ToDo.md (99%) create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/lexer/detect-kind.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/lexer/kinds.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/lexer/lexer.go rename vendor/github.com/shoriwe/gplasma/pkg/{compiler => }/lexer/token.go (57%) create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-binary.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-comment.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-float.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-hex.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-interger.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-numeric.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-octal.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-repeatable-operator.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-scientific-float.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-single-operator.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-string.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-word.go rename vendor/github.com/shoriwe/gplasma/pkg/{compiler => }/parser/ToDo.md (100%) create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/parser/common.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/parser/errors.go rename vendor/github.com/shoriwe/gplasma/pkg/{compiler => }/parser/grammar.bnf (100%) create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/parser/iter.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/parser/names.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/parser/parse-array-expression.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/parser/parse-assignment-statement.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/parser/parse-begin-statement.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/parser/parse-binary-expression.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/parser/parse-break-statement.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/parser/parse-class-statement.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/parser/parse-continue-statement.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/parser/parse-defer-statement.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/parser/parse-delete-statement.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/parser/parse-do-while.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/parser/parse-end-statement.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/parser/parse-for-statement.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/parser/parse-function-definition-statement.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/parser/parse-generator-expression.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/parser/parse-generator-statement.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/parser/parse-hash-expression.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/parser/parse-if-one-liner-expression.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/parser/parse-if-statement.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/parser/parse-index-expression.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/parser/parse-interface-statement.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/parser/parse-lambda-expression.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/parser/parse-literal-expression.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/parser/parse-method-invocation-expression.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/parser/parse-module-statement.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/parser/parse-operand.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/parser/parse-parentheses-expression.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/parser/parse-pass-statement.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/parser/parse-return-statement.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/parser/parse-selector-expression.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/parser/parse-super-statement.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/parser/parse-switch-statement.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/parser/parse-unary-expression.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/parser/parse-unless-one-liner-expression.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/parser/parse-unless-statement.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/parser/parse-until-statement.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/parser/parse-while-statement.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/parser/parse-yield-statement.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/parser/parser-primary-expression.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/parser/parser.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/checks/checks.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/checks/invalid-break.pm create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/checks/invalid-continue.pm create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/checks/invalid-return.pm create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/checks/invalid-yield.pm create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/checks/valid-script.pm create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/anon-identifier.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-array.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-assign.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-binary.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-call.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-class.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-defer.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-delete.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-do-while.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-expression.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-for.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-function.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-generator.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-hash.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-identifier.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-if-one-liner.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-if.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-index.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-interface.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-lambda.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-literal.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-loop-operations.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-module.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-parentheses.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-pass.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-return-yield.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-selector.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-statement.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-super.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-switch.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-tuple.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-unary.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-unless.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-until.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-while.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/label.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-array.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-assignment.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-binary.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-call.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-class.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-defer.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-delete.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-do-while.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-expression.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-function.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-generator-expr.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-generator.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-hash.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-identifier.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-if-one-liner.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-if.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-index.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-lambda.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-literals.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-loop-operations.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-module.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-return-yield.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-selector.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-statement.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-super.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-tuple.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-unary.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-while.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transformations.go delete mode 100644 vendor/github.com/shoriwe/gplasma/pkg/tools/index.go delete mode 100644 vendor/github.com/shoriwe/gplasma/pkg/tools/string.go delete mode 100644 vendor/github.com/shoriwe/gplasma/pkg/vm/ToDo.md delete mode 100644 vendor/github.com/shoriwe/gplasma/pkg/vm/bytecode.go delete mode 100644 vendor/github.com/shoriwe/gplasma/pkg/vm/call.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/vm/class.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/vm/config.go delete mode 100644 vendor/github.com/shoriwe/gplasma/pkg/vm/constructor.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/vm/debug.go delete mode 100644 vendor/github.com/shoriwe/gplasma/pkg/vm/default.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/vm/do.go delete mode 100644 vendor/github.com/shoriwe/gplasma/pkg/vm/error.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/vm/errors.go delete mode 100644 vendor/github.com/shoriwe/gplasma/pkg/vm/execute.go delete mode 100644 vendor/github.com/shoriwe/gplasma/pkg/vm/function_names.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/vm/hash-internal.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/vm/hash.go delete mode 100644 vendor/github.com/shoriwe/gplasma/pkg/vm/hashing.go delete mode 100644 vendor/github.com/shoriwe/gplasma/pkg/vm/hashtable.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/vm/init.go delete mode 100644 vendor/github.com/shoriwe/gplasma/pkg/vm/instruction_information.go delete mode 100644 vendor/github.com/shoriwe/gplasma/pkg/vm/instructions.go delete mode 100644 vendor/github.com/shoriwe/gplasma/pkg/vm/iterator.go delete mode 100644 vendor/github.com/shoriwe/gplasma/pkg/vm/module.go delete mode 100644 vendor/github.com/shoriwe/gplasma/pkg/vm/op_codes.go delete mode 100644 vendor/github.com/shoriwe/gplasma/pkg/vm/plasma.go delete mode 100644 vendor/github.com/shoriwe/gplasma/pkg/vm/proxy_object.go delete mode 100644 vendor/github.com/shoriwe/gplasma/pkg/vm/stack.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/vm/symbol-table.go delete mode 100644 vendor/github.com/shoriwe/gplasma/pkg/vm/symbol_table.go delete mode 100644 vendor/github.com/shoriwe/gplasma/pkg/vm/tools.go delete mode 100644 vendor/github.com/shoriwe/gplasma/pkg/vm/type.go delete mode 100644 vendor/github.com/shoriwe/gplasma/pkg/vm/type_names.go create mode 100644 vendor/github.com/shoriwe/gplasma/pkg/vm/vm.go delete mode 100644 vendor/github.com/shoriwe/gplasma/plasma.go diff --git a/vendor/github.com/shoriwe/gplasma/.gitattributes b/vendor/github.com/shoriwe/gplasma/.gitattributes deleted file mode 100644 index dfe0770..0000000 --- a/vendor/github.com/shoriwe/gplasma/.gitattributes +++ /dev/null @@ -1,2 +0,0 @@ -# Auto detect text files and perform LF normalization -* text=auto diff --git a/vendor/github.com/shoriwe/gplasma/.gitignore b/vendor/github.com/shoriwe/gplasma/.gitignore deleted file mode 100644 index cb82a36..0000000 --- a/vendor/github.com/shoriwe/gplasma/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.idea/* diff --git a/vendor/github.com/shoriwe/gplasma/README.md b/vendor/github.com/shoriwe/gplasma/README.md deleted file mode 100644 index ab88232..0000000 --- a/vendor/github.com/shoriwe/gplasma/README.md +++ /dev/null @@ -1,142 +0,0 @@ -# plasma - -## Documentation - -You can find documentation in: - -[Documentation](https://shoriwe.github.io) - -## Description - -**`plasma`** is a dynamic programming language highly inspired in **`ruby`** syntax and semantics with interfaces and -design focused in application embedding. - -## Try it - -You can have a working interpreter by compiling `cmd/plasma`. - -- You can compile a binary with (using **`Go-1.16`**) - -```shell -go install github.com/shoriwe/gplasma/cmd/plasma@latest -``` - -``` -...>plasma [MODE] [FLAG [FLAG [FLAG]]] [PROGRAM [PROGRAM [PROGRAM]]] - -[+] Notes - - No PROGRAM arguments will spawn a REPL - -[+] Flags - -h, --help Show this help message - -[+] Modes - module tool to install, uninstall and initialize modules - -[+] Environment Variables - NoColor -> TRUE or FALSE Disable color printing for this CLI - SitePackages -> PATH This is the path to the Site-Packages of the running VM; Default is PATH/TO/PLASMA/EXECUTABLE/site-packages -``` - -## Features - -### Embedding - -**`plasma`** was designed to be embedded in other go applications, you should do it like: - -```go -package main - -import ( - "fmt" - "github.com/shoriwe/gplasma" - "github.com/shoriwe/gplasma/pkg/std/features/importlib" - "os" -) - -var ( - files []string - virtualMachine *gplasma.VirtualMachine - sitePackagesPath = "site-packages" -) - -// Setup the vm based on the options -func setupVM() { - virtualMachine = gplasma.NewVirtualMachine() - currentDir, err := os.Getwd() - if err != nil { - currentDir = "." - } - importSystem := importlib.NewImporter() - // Load Default modules to use with the VM - importSystem.LoadModule(regex.Regex) - // - virtualMachine.LoadFeature( - importSystem.Result( - importlib.NewRealFileSystem(sitePackagesPath), - importlib.NewRealFileSystem(currentDir), - ), - ) -} - -func program() { - setupVM() - for _, filePath := range files { - fileHandler, openError := os.Open(filePath) - if openError != nil { - _, _ = fmt.Fprintf(os.Stderr, openError.Error()) - os.Exit(1) - } - content, readingError := io.ReadAll(fileHandler) - if readingError != nil { - _, _ = fmt.Fprintf(os.Stderr, readingError.Error()) - os.Exit(1) - } - result, success := virtualMachine.ExecuteMain(string(content)) - if !success { - _, _ = fmt.Fprintf(os.Stderr, "[%s] %s: %s\n", color.RedString("-"), result.TypeName(), result.String) - os.Exit(1) - } - } -} -``` - -In the future there will be a simpler way to embed it in your application, which shouldn't break the one provided -before. - -## Notable Differences - -The major difference between **`ruby`** and **`plasma`** is that in the first the last expression in a function will be -returned without specifying the keyboard `return` but in **`plasma`** you should. - -Another one will be that function calls, will always need parentheses to be executed, other way their will be evaluated -as objects. - -Example: - -This example shows a valid **`ruby`** code that returns from a function a string. - -```ruby -def hello() - "Hello World" -end - -puts hello -``` - -But in **`plasma`** you should code it something like: - -```ruby -def hello() - return "Hello World" # Notice that here is used the keyboard "return" -end - -println(hello()) -``` - -# Useful references - -This where useful references that made this project possible. - -- [BNF grammar](https://ruby-doc.org/docs/ruby-doc-bundle/Manual/man-1.4/yacc.html) -- [Syntax Documentation](https://ruby-doc.org/docs/ruby-doc-bundle/Manual/man-1.4/syntax.html) diff --git a/vendor/github.com/shoriwe/gplasma/ToDo.md b/vendor/github.com/shoriwe/gplasma/ToDo.md deleted file mode 100644 index d78719e..0000000 --- a/vendor/github.com/shoriwe/gplasma/ToDo.md +++ /dev/null @@ -1,95 +0,0 @@ -### Language - -This are the expressions and statements that **`plasma`** currently supports: - -- [X] Expressions - - [X] Literals - - [X] Integers - - [X] Decimal - - [X] Hex - - [X] Binary - - [X] Octal - - [X] Float - - [X] Basic - - [X] Scientific - - [X] String - - [X] Single Quote - - [X] Double Quote - - [X] Bytes - - [X] Bool - - [X] True - - [X] False - - [X] None - - [X] Complex types - - [X] Tuple - - [X] Array - - [X] Hash Table - - [X] Unary Expressions - - [X] Negate Bits - - [X] Negate Bool - - [X] Binary Expressions - - [X] Add - - [X] Sub - - [X] Mul - - [X] Div - - [X] Mod - - [X] Pow - - [X] BitXor - - [X] BitAnd - - [X] BitOr - - [X] BitLeft - - [X] BitRight - - [X] And - - [X] Or - - [X] Xor - - [X] Equals - - [X] NotEquals - - [X] GreaterThan - - [X] LessThan - - [X] GreaterThanOrEqual - - [X] LessThanOrEqual - - [X] Lambda Expressions - - [X] One Line If - - [X] One Line Unless - - [X] Identifiers - - [X] Generators - - [X] Call - - [X] Function - - [X] Type - - [X] Index - - [X] Parentheses Expressions - - [X] Selector Expressions -- [ ] Statements - - [X] Assign Statement - - [ ] DeferStatement - - [x] Do While - - [X] Continue - - [X] Break - - [X] Redo - - [X] While - - [X] Continue - - [X] Break - - [X] Redo - - [X] Until - - [X] Continue - - [X] Break - - [X] Redo - - [X] For Loop - - [X] Continue - - [X] Break - - [X] Redo - - [X] If - Else - Elif - - [X] Unless - Else - Elif - - [X] Switch - - [X] Module - - [X] Function Definition - - [X] Interface - - [X] Class - - [X] Raise - - [X] Try - Except - - [X] Begin - - [X] End - - [X] Return - - [X] Super - - [X] Pass - - [ ] Yield diff --git a/vendor/github.com/shoriwe/gplasma/count-lines.py b/vendor/github.com/shoriwe/gplasma/count-lines.py deleted file mode 100644 index 28b300b..0000000 --- a/vendor/github.com/shoriwe/gplasma/count-lines.py +++ /dev/null @@ -1,19 +0,0 @@ -import os -import os.path - - -def main(): - count = 0 - for path, _, files in os.walk("."): - if ".git" in path: - continue - for file in files: - if ".go" not in file: - continue - with open(os.path.join(path, file), "rb") as file_object: - count += file_object.read().count(b"\r") - print(count) - - -if __name__ == "__main__": - main() \ No newline at end of file diff --git a/vendor/github.com/shoriwe/gplasma/go.mod b/vendor/github.com/shoriwe/gplasma/go.mod deleted file mode 100644 index f92f213..0000000 --- a/vendor/github.com/shoriwe/gplasma/go.mod +++ /dev/null @@ -1,8 +0,0 @@ -module github.com/shoriwe/gplasma - -go 1.16 - -require ( - github.com/fatih/color v1.12.0 - github.com/otiai10/copy v1.6.0 -) diff --git a/vendor/github.com/shoriwe/gplasma/go.sum b/vendor/github.com/shoriwe/gplasma/go.sum deleted file mode 100644 index d0e6fad..0000000 --- a/vendor/github.com/shoriwe/gplasma/go.sum +++ /dev/null @@ -1,15 +0,0 @@ -github.com/fatih/color v1.12.0 h1:mRhaKNwANqRgUBGKmnI5ZxEk7QXmjQeCcuYFMX2bfcc= -github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= -github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= -github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/otiai10/copy v1.6.0 h1:IinKAryFFuPONZ7cm6T6E2QX/vcJwSnlaA5lfoaXIiQ= -github.com/otiai10/copy v1.6.0/go.mod h1:XWfuS3CrI0R6IE0FbgHsEazaXO8G0LpMp9o8tos0x4E= -github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= -github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= -github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= -github.com/otiai10/mint v1.3.2/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae h1:/WDfKMnPU+m5M4xB+6x4kaepxRw6jWvR5iDRdvjHgy8= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/vendor/github.com/shoriwe/gplasma/pkg/compiler/ast/ToDo.md b/vendor/github.com/shoriwe/gplasma/pkg/ast/ToDo.md similarity index 100% rename from vendor/github.com/shoriwe/gplasma/pkg/compiler/ast/ToDo.md rename to vendor/github.com/shoriwe/gplasma/pkg/ast/ToDo.md diff --git a/vendor/github.com/shoriwe/gplasma/pkg/ast/expression.go b/vendor/github.com/shoriwe/gplasma/pkg/ast/expression.go new file mode 100644 index 0000000..568429a --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/ast/expression.go @@ -0,0 +1,112 @@ +package ast + +import ( + lexer2 "github.com/shoriwe/gplasma/pkg/lexer" +) + +type ( + Expression interface { + Node + E() + } + + ArrayExpression struct { + Expression + Values []Expression + } + + TupleExpression struct { + Expression + Values []Expression + } + + KeyValue struct { + Key Expression + Value Expression + } + + HashExpression struct { + Expression + Values []*KeyValue + } + + Identifier struct { + Expression + Token *lexer2.Token + } + + BasicLiteralExpression struct { + Expression + Token *lexer2.Token + Kind lexer2.Kind + DirectValue lexer2.DirectValue + } + + BinaryExpression struct { + Expression + LeftHandSide Expression + Operator *lexer2.Token + RightHandSide Expression + } + + UnaryExpression struct { + Expression + Operator *lexer2.Token + X Expression + } + + ParenthesesExpression struct { + Expression + X Expression + } + + LambdaExpression struct { + Expression + Arguments []*Identifier + Code Expression + } + + GeneratorExpression struct { + Expression + Operation Expression + Receivers []*Identifier + Source Expression + } + + SelectorExpression struct { + Expression + X Expression + Identifier *Identifier + } + + MethodInvocationExpression struct { + Expression + Function Expression + Arguments []Expression + } + + IndexExpression struct { + Expression + Source Expression + Index Expression + } + + IfOneLinerExpression struct { + Expression + Result Expression + Condition Expression + ElseResult Expression + } + + UnlessOneLinerExpression struct { + Expression + Result Expression + Condition Expression + ElseResult Expression + } + + SuperExpression struct { + Expression + X Expression + } +) diff --git a/vendor/github.com/shoriwe/gplasma/pkg/ast/node.go b/vendor/github.com/shoriwe/gplasma/pkg/ast/node.go new file mode 100644 index 0000000..a06d195 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/ast/node.go @@ -0,0 +1,14 @@ +package ast + +type ( + Node interface { + N() + } + + Program struct { + Node + Begin *BeginStatement + End *EndStatement + Body []Node + } +) diff --git a/vendor/github.com/shoriwe/gplasma/pkg/ast/statement.go b/vendor/github.com/shoriwe/gplasma/pkg/ast/statement.go new file mode 100644 index 0000000..a8a6ea0 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/ast/statement.go @@ -0,0 +1,153 @@ +package ast + +import ( + "github.com/shoriwe/gplasma/pkg/lexer" +) + +type ( + Statement interface { + S() + Node + } + + AssignStatement struct { + Statement + LeftHandSide Expression // Identifiers or Selectors + AssignOperator *lexer.Token + RightHandSide Expression + } + + DoWhileStatement struct { + Statement + Condition Expression + Body []Node + } + + WhileLoopStatement struct { + Statement + Condition Expression + Body []Node + } + + UntilLoopStatement struct { + Statement + Condition Expression + Body []Node + } + + ForLoopStatement struct { + Statement + Receivers []*Identifier + Source Expression + Body []Node + } + + ElifBlock struct { + Condition Expression + Body []Node + } + + IfStatement struct { + Statement + Condition Expression + Body []Node + ElifBlocks []ElifBlock + Else []Node + } + + UnlessStatement struct { + Statement + Condition Expression + Body []Node + ElifBlocks []ElifBlock + Else []Node + } + + CaseBlock struct { + Cases []Expression + Body []Node + } + + SwitchStatement struct { + Statement + Target Expression + CaseBlocks []*CaseBlock + Default []Node + } + + ModuleStatement struct { + Statement + Name *Identifier + Body []Node + } + + FunctionDefinitionStatement struct { + Statement + Name *Identifier + Arguments []*Identifier + Body []Node + } + + GeneratorDefinitionStatement struct { + Statement + Name *Identifier + Arguments []*Identifier + Body []Node + } + + InterfaceStatement struct { + Statement + Name *Identifier + Bases []Expression + MethodDefinitions []*FunctionDefinitionStatement + } + + ClassStatement struct { + Statement + Name *Identifier + Bases []Expression // Identifiers and selectors + Body []Node + } + + BeginStatement struct { + Statement + Body []Node + } + + EndStatement struct { + Statement + Body []Node + } + + ReturnStatement struct { + Statement + Results []Expression + } + + YieldStatement struct { + Statement + Results []Expression + } + + ContinueStatement struct { + Statement + } + + BreakStatement struct { + Statement + } + + PassStatement struct { + Statement + } + + DeleteStatement struct { + Statement + X Expression + } + + DeferStatement struct { + Statement + X *MethodInvocationExpression + } +) diff --git a/vendor/github.com/shoriwe/gplasma/pkg/ast/walk.go b/vendor/github.com/shoriwe/gplasma/pkg/ast/walk.go new file mode 100644 index 0000000..5b41851 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/ast/walk.go @@ -0,0 +1,200 @@ +package ast + +import ( + "fmt" + "reflect" +) + +type Visitor interface { + Visit(node Node) Visitor +} + +func walk(visitor Visitor, node Node) { + // Visit the node + if visitor = visitor.Visit(node); visitor == nil { + return + } + // Visit its children + switch n := node.(type) { + case *Identifier, *BasicLiteralExpression: + break + case *Program: + if n.Begin != nil { + walk(visitor, n.Begin) + } + for _, child := range n.Body { + walk(visitor, child) + } + if n.End != nil { + walk(visitor, n.End) + } + case *ArrayExpression: + for _, value := range n.Values { + walk(visitor, value) + } + case *TupleExpression: + for _, value := range n.Values { + walk(visitor, value) + } + case *HashExpression: + for _, keyValue := range n.Values { + walk(visitor, keyValue.Key) + walk(visitor, keyValue.Value) + } + case *BinaryExpression: + walk(visitor, n.LeftHandSide) + walk(visitor, n.RightHandSide) + case *UnaryExpression: + walk(visitor, n.X) + case *ParenthesesExpression: + walk(visitor, n.X) + case *LambdaExpression: + for _, argument := range n.Arguments { + walk(visitor, argument) + } + walk(visitor, n.Code) + case *GeneratorExpression: + walk(visitor, n.Operation) + for _, identifier := range n.Receivers { + walk(visitor, identifier) + } + walk(visitor, n.Source) + case *SelectorExpression: + walk(visitor, n.X) + walk(visitor, n.Identifier) + case *MethodInvocationExpression: + walk(visitor, n.Function) + for _, argument := range n.Arguments { + walk(visitor, argument) + } + case *IndexExpression: + walk(visitor, n.Source) + walk(visitor, n.Index) + case *IfOneLinerExpression: + walk(visitor, n.Result) + walk(visitor, n.Condition) + walk(visitor, n.ElseResult) + case *UnlessOneLinerExpression: + walk(visitor, n.Result) + walk(visitor, n.Condition) + walk(visitor, n.ElseResult) + case *AssignStatement: + walk(visitor, n.LeftHandSide) + walk(visitor, n.RightHandSide) + case *DoWhileStatement: + walk(visitor, n.Condition) + for _, bodyNode := range n.Body { + walk(visitor, bodyNode) + } + case *WhileLoopStatement: + walk(visitor, n.Condition) + for _, bodyNode := range n.Body { + walk(visitor, bodyNode) + } + case *UntilLoopStatement: + walk(visitor, n.Condition) + for _, bodyNode := range n.Body { + walk(visitor, bodyNode) + } + case *ForLoopStatement: + for _, receiver := range n.Receivers { + walk(visitor, receiver) + } + walk(visitor, n.Source) + for _, bodyNode := range n.Body { + walk(visitor, bodyNode) + } + case *SwitchStatement: + walk(visitor, n.Target) + for _, caseBlock := range n.CaseBlocks { + for _, case_ := range caseBlock.Cases { + walk(visitor, case_) + } + for _, bodyNode := range caseBlock.Body { + walk(visitor, bodyNode) + } + } + for _, bodyNode := range n.Default { + walk(visitor, bodyNode) + } + case *ModuleStatement: + walk(visitor, n.Name) + for _, bodyNode := range n.Body { + walk(visitor, bodyNode) + } + case *FunctionDefinitionStatement: + walk(visitor, n.Name) + for _, argument := range n.Arguments { + walk(visitor, argument) + } + for _, bodyNode := range n.Body { + walk(visitor, bodyNode) + } + case *InterfaceStatement: + walk(visitor, n.Name) + for _, base := range n.Bases { + walk(visitor, base) + } + for _, methodDefinition := range n.MethodDefinitions { + walk(visitor, methodDefinition) + } + case *ClassStatement: + walk(visitor, n.Name) + for _, base := range n.Bases { + walk(visitor, base) + } + for _, bodyNode := range n.Body { + walk(visitor, bodyNode) + } + case *BeginStatement: + for _, bodyNode := range n.Body { + walk(visitor, bodyNode) + } + case *EndStatement: + for _, bodyNode := range n.Body { + walk(visitor, bodyNode) + } + case *ReturnStatement: + for _, value := range n.Results { + walk(visitor, value) + } + case *YieldStatement: + for _, value := range n.Results { + walk(visitor, value) + } + case *IfStatement: + walk(visitor, n.Condition) + for _, bodyChild := range n.Body { + walk(visitor, bodyChild) + } + for _, elifBlock := range n.ElifBlocks { + walk(visitor, elifBlock.Condition) + for _, elifBlockChild := range elifBlock.Body { + walk(visitor, elifBlockChild) + } + } + case *UnlessStatement: + walk(visitor, n.Condition) + for _, bodyChild := range n.Body { + walk(visitor, bodyChild) + } + for _, elifBlock := range n.ElifBlocks { + walk(visitor, elifBlock.Condition) + for _, elifBlockChild := range elifBlock.Body { + walk(visitor, elifBlockChild) + } + } + case *DeleteStatement: + walk(visitor, n.X) + case *PassStatement: + return + case nil: + break // Ignore nil + default: + panic(fmt.Sprintf("unknown node type %s", reflect.TypeOf(node).String())) + } +} + +func Walk(visitor Visitor, node Node) { + walk(visitor, node) +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/ast2/expression.go b/vendor/github.com/shoriwe/gplasma/pkg/ast2/expression.go new file mode 100644 index 0000000..81f8a72 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/ast2/expression.go @@ -0,0 +1,156 @@ +package ast2 + +const ( + Not UnaryOperator = iota + Positive + Negative + NegateBits + + And BinaryOperator = iota + Or + Xor + In + Is + Implements + Equals + NotEqual + GreaterThan + GreaterOrEqualThan + LessThan + LessOrEqualThan + BitwiseOr + BitwiseXor + BitwiseAnd + BitwiseLeft + BitwiseRight + Add + Sub + Mul + Div + FloorDiv + Modulus + PowerOf +) + +type ( + BinaryOperator int + UnaryOperator int + Expression interface { + Node + E2() + } + + Assignable interface { + Expression + A() + } + + Binary struct { + Expression + Left, Right Expression + Operator BinaryOperator + } + + Unary struct { + Expression + Operator UnaryOperator + X Expression + } + + IfOneLiner struct { + Expression + Condition, Result, Else Expression + } + + Array struct { + Expression + Values []Expression + } + + Tuple struct { + Expression + Values []Expression + } + + KeyValue struct { + Key, Value Expression + } + + Hash struct { + Expression + Values []*KeyValue + } + + Identifier struct { + Assignable + Symbol string + } + + Integer struct { + Expression + Value int64 + } + + Float struct { + Expression + Value float64 + } + + String struct { + Expression + Contents []byte + } + + Bytes struct { + Expression + Contents []byte + } + + True struct { + Expression + } + + False struct { + Expression + } + + None struct { + Expression + } + + Lambda struct { + Expression + Arguments []*Identifier + Result Expression + } + + Generator struct { + Expression + Operation Expression + Receivers []*Identifier + Source Expression + } + + Selector struct { + Assignable + X Expression + Identifier *Identifier + } + + FunctionCall struct { + Expression + Function Expression + Arguments []Expression + } + + Index struct { + Assignable + Source Expression + Index Expression + } + + Super struct { + Expression + X Expression + } +) diff --git a/vendor/github.com/shoriwe/gplasma/pkg/ast2/node.go b/vendor/github.com/shoriwe/gplasma/pkg/ast2/node.go new file mode 100644 index 0000000..49a2ec9 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/ast2/node.go @@ -0,0 +1,8 @@ +package ast2 + +type ( + Node interface { + N2() + } + Program []Node +) diff --git a/vendor/github.com/shoriwe/gplasma/pkg/ast2/statement.go b/vendor/github.com/shoriwe/gplasma/pkg/ast2/statement.go new file mode 100644 index 0000000..f6fa2ad --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/ast2/statement.go @@ -0,0 +1,81 @@ +package ast2 + +type ( + AssignmentOperator int + Statement interface { + Node + S2() + } + Assignment struct { + Statement + Left Assignable + Right Expression + } + DoWhile struct { + Statement + Body []Node + Condition Expression + } + While struct { + Statement + Setup []Node + Condition Expression + Body []Node + } + If struct { + Statement + SwitchSetup *Assignment + Condition Expression + Body []Node + Else []Node + } + Module struct { + Statement + Name *Identifier + Body []Node + } + FunctionDefinition struct { + Statement + Name *Identifier + Arguments []*Identifier + Body []Node + } + GeneratorDefinition struct { + Statement + Name *Identifier + Arguments []*Identifier + Body []Node + } + Class struct { + Statement + Name *Identifier + Bases []Expression + Body []Node + } + Return struct { + Statement + Result Expression + } + Yield struct { + Statement + Result Expression + } + Continue struct { + Statement + } + Break struct { + Statement + } + Pass struct { + Statement + } + + Delete struct { + Statement + X Assignable + } + Defer struct { + Statement + X Expression + } +) diff --git a/vendor/github.com/shoriwe/gplasma/pkg/ast3/expression.go b/vendor/github.com/shoriwe/gplasma/pkg/ast3/expression.go new file mode 100644 index 0000000..a9948c6 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/ast3/expression.go @@ -0,0 +1,100 @@ +package ast3 + +type ( + Expression interface { + Node + E3() + } + Assignable interface { + Expression + A2() + } + Function struct { + Expression + Arguments []*Identifier + Body []Node + } + Class struct { + Expression + Bases []Expression + Body []Node + } + Call struct { + Expression + Function Expression + Arguments []Expression + } + + Array struct { + Expression + Values []Expression + } + + Tuple struct { + Expression + Values []Expression + } + + KeyValue struct { + Key, Value Expression + } + + Hash struct { + Expression + Values []*KeyValue + } + + Identifier struct { + Assignable + Symbol string + } + + Integer struct { + Expression + Value int64 + } + + Float struct { + Expression + Value float64 + } + + String struct { + Expression + Contents []byte + } + + Bytes struct { + Expression + Contents []byte + } + + True struct { + Expression + } + + False struct { + Expression + } + + None struct { + Expression + } + + Selector struct { + Assignable + X Expression + Identifier *Identifier + } + + Index struct { + Assignable + Source Expression + Index Expression + } + + Super struct { + Expression + X Expression + } +) diff --git a/vendor/github.com/shoriwe/gplasma/pkg/ast3/node.go b/vendor/github.com/shoriwe/gplasma/pkg/ast3/node.go new file mode 100644 index 0000000..a579ce7 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/ast3/node.go @@ -0,0 +1,8 @@ +package ast3 + +type ( + Node interface { + N3() + } + Program []Node +) diff --git a/vendor/github.com/shoriwe/gplasma/pkg/ast3/statement.go b/vendor/github.com/shoriwe/gplasma/pkg/ast3/statement.go new file mode 100644 index 0000000..ab3fe00 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/ast3/statement.go @@ -0,0 +1,42 @@ +package ast3 + +type ( + Statement interface { + Node + S3() + } + Assignment struct { + Statement + Left Assignable + Right Expression + } + Label struct { + Statement + Code int + } + Jump struct { + Statement + Target *Label + } + ContinueJump Jump + BreakJump Jump + IfJump struct { + Statement + Condition Expression + Target *Label + } + Return struct { + Statement + Result Expression + } + Yield Return + + Delete struct { + Statement + X Assignable + } + Defer struct { + Statement + X Expression + } +) diff --git a/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-array.go b/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-array.go new file mode 100644 index 0000000..58dfeb8 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-array.go @@ -0,0 +1,18 @@ +package assembler + +import ( + "github.com/shoriwe/gplasma/pkg/ast3" + "github.com/shoriwe/gplasma/pkg/bytecode/opcodes" + "github.com/shoriwe/gplasma/pkg/common" +) + +func (a *assembler) Array(array *ast3.Array) []byte { + var result []byte + for _, value := range array.Values { + result = append(result, a.Expression(value)...) + result = append(result, opcodes.Push) + } + result = append(result, opcodes.NewArray) + result = append(result, common.IntToBytes(len(array.Values))...) + return result +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-assignment.go b/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-assignment.go new file mode 100644 index 0000000..a1d4181 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-assignment.go @@ -0,0 +1,40 @@ +package assembler + +import ( + "fmt" + "github.com/shoriwe/gplasma/pkg/ast3" + "github.com/shoriwe/gplasma/pkg/bytecode/opcodes" + "github.com/shoriwe/gplasma/pkg/common" + magic_functions "github.com/shoriwe/gplasma/pkg/common/magic-functions" + "reflect" +) + +func (a *assembler) Assignment(assign *ast3.Assignment) []byte { + result := a.Expression(assign.Right) + result = append(result, opcodes.Push) + switch left := assign.Left.(type) { + case *ast3.Identifier: + result = append(result, opcodes.IdentifierAssign) + result = append(result, common.IntToBytes(len(left.Symbol))...) + result = append(result, []byte(left.Symbol)...) + case *ast3.Selector: + result = append(result, a.Expression(left.X)...) + result = append(result, opcodes.Push) + result = append(result, opcodes.SelectorAssign) + result = append(result, common.IntToBytes(len(left.Identifier.Symbol))...) + result = append(result, []byte(left.Identifier.Symbol)...) + case *ast3.Index: + return a.Call(&ast3.Call{ + Function: &ast3.Selector{ + X: left.Source, + Identifier: &ast3.Identifier{ + Symbol: magic_functions.Set, + }, + }, + Arguments: []ast3.Expression{left.Index, assign.Right}, + }) + default: + panic(fmt.Sprintf("unknown left hand side type %s", reflect.TypeOf(left).String())) + } + return result +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-call.go b/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-call.go new file mode 100644 index 0000000..d7b8dbf --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-call.go @@ -0,0 +1,20 @@ +package assembler + +import ( + "github.com/shoriwe/gplasma/pkg/ast3" + "github.com/shoriwe/gplasma/pkg/bytecode/opcodes" + "github.com/shoriwe/gplasma/pkg/common" +) + +func (a *assembler) Call(call *ast3.Call) []byte { + var result []byte + for _, argument := range call.Arguments { + result = append(result, a.Expression(argument)...) + result = append(result, opcodes.Push) + } + result = append(result, a.Expression(call.Function)...) + result = append(result, opcodes.Push) + result = append(result, opcodes.Call) + result = append(result, common.IntToBytes(len(call.Arguments))...) + return result +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-class.go b/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-class.go new file mode 100644 index 0000000..750135f --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-class.go @@ -0,0 +1,26 @@ +package assembler + +import ( + "github.com/shoriwe/gplasma/pkg/ast3" + "github.com/shoriwe/gplasma/pkg/bytecode/opcodes" + "github.com/shoriwe/gplasma/pkg/common" +) + +func (a *assembler) Class(class *ast3.Class) []byte { + var bases []byte + for _, base := range class.Bases { + bases = append(bases, a.Expression(base)...) + bases = append(bases, opcodes.Push) + } + var body []byte + for _, node := range class.Body { + body = append(body, a.assemble(node)...) + } + var result []byte + result = append(result, bases...) + result = append(result, opcodes.NewClass) + result = append(result, common.IntToBytes(len(class.Bases))...) + result = append(result, common.IntToBytes(len(body))...) + result = append(result, body...) + return result +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-defer.go b/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-defer.go new file mode 100644 index 0000000..32e533e --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-defer.go @@ -0,0 +1,15 @@ +package assembler + +import ( + "github.com/shoriwe/gplasma/pkg/ast3" + "github.com/shoriwe/gplasma/pkg/bytecode/opcodes" + "github.com/shoriwe/gplasma/pkg/common" +) + +func (a *assembler) Defer(defer_ *ast3.Defer) []byte { + expression := a.Expression(defer_.X) + result := []byte{opcodes.Defer} + result = append(result, common.IntToBytes(len(expression))...) + result = append(result, expression...) + return result +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-delete.go b/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-delete.go new file mode 100644 index 0000000..6167dfd --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-delete.go @@ -0,0 +1,41 @@ +package assembler + +import ( + "fmt" + "github.com/shoriwe/gplasma/pkg/ast3" + "github.com/shoriwe/gplasma/pkg/bytecode/opcodes" + "github.com/shoriwe/gplasma/pkg/common" + magic_functions "github.com/shoriwe/gplasma/pkg/common/magic-functions" + "reflect" +) + +func (a *assembler) Delete(del *ast3.Delete) []byte { + var result []byte + switch x := del.X.(type) { + case *ast3.Identifier: + result = append(result, opcodes.DeleteIdentifier) + result = append(result, common.IntToBytes(len(x.Symbol))...) + result = append(result, []byte(x.Symbol)...) + case *ast3.Selector: + result = append(result, a.Expression(x.X)...) + result = append(result, opcodes.Push) + result = append(result, opcodes.DeleteSelector) + result = append(result, common.IntToBytes(len(x.Identifier.Symbol))...) + result = append(result, []byte(x.Identifier.Symbol)...) + case *ast3.Index: + return a.Call( + &ast3.Call{ + Function: &ast3.Selector{ + X: x.Source, + Identifier: &ast3.Identifier{ + Symbol: magic_functions.Del, + }, + }, + Arguments: []ast3.Expression{x.Index}, + }, + ) + default: + panic(fmt.Sprintf("invalid type of delete target %s", reflect.TypeOf(x).String())) + } + return result +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-expression.go b/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-expression.go new file mode 100644 index 0000000..be635d4 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-expression.go @@ -0,0 +1,51 @@ +package assembler + +import ( + "fmt" + "github.com/shoriwe/gplasma/pkg/ast3" + "reflect" +) + +func (a *assembler) Expression(expr ast3.Expression) []byte { + if expr == nil { + return nil + } + switch e := expr.(type) { + case *ast3.Function: + return a.Function(e) + case *ast3.Class: + return a.Class(e) + case *ast3.Call: + return a.Call(e) + case *ast3.Array: + return a.Array(e) + case *ast3.Tuple: + return a.Tuple(e) + case *ast3.Hash: + return a.Hash(e) + case *ast3.Identifier: + return a.Identifier(e) + case *ast3.Integer: + return a.Integer(e) + case *ast3.Float: + return a.Float(e) + case *ast3.String: + return a.String(e) + case *ast3.Bytes: + return a.Bytes(e) + case *ast3.True: + return a.True(e) + case *ast3.False: + return a.False(e) + case *ast3.None: + return a.None(e) + case *ast3.Selector: + return a.Selector(e) + case *ast3.Index: + return a.Index(e) + case *ast3.Super: + return a.Super(e) + default: + panic(fmt.Sprintf("unknown expression type %s", reflect.TypeOf(e).String())) + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-function.go b/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-function.go new file mode 100644 index 0000000..10ee35d --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-function.go @@ -0,0 +1,26 @@ +package assembler + +import ( + "github.com/shoriwe/gplasma/pkg/ast3" + "github.com/shoriwe/gplasma/pkg/bytecode/opcodes" + "github.com/shoriwe/gplasma/pkg/common" +) + +func (a *assembler) Function(function *ast3.Function) []byte { + arguments := make([]byte, 0, len(function.Arguments)) + for _, argument := range function.Arguments { + arguments = append(arguments, common.IntToBytes(len(argument.Symbol))...) + arguments = append(arguments, []byte(argument.Symbol)...) + } + body := make([]byte, 0, len(function.Body)) + for _, node := range function.Body { + body = append(body, a.assemble(node)...) + } + var result []byte + result = append(result, opcodes.NewFunction) + result = append(result, common.IntToBytes(len(function.Arguments))...) + result = append(result, arguments...) + result = append(result, common.IntToBytes(len(body))...) + result = append(result, body...) + return result +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-hash.go b/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-hash.go new file mode 100644 index 0000000..b4c983a --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-hash.go @@ -0,0 +1,20 @@ +package assembler + +import ( + "github.com/shoriwe/gplasma/pkg/ast3" + "github.com/shoriwe/gplasma/pkg/bytecode/opcodes" + "github.com/shoriwe/gplasma/pkg/common" +) + +func (a *assembler) Hash(hash *ast3.Hash) []byte { + var result []byte + for _, value := range hash.Values { + result = append(result, a.Expression(value.Value)...) + result = append(result, opcodes.Push) + result = append(result, a.Expression(value.Key)...) + result = append(result, opcodes.Push) + } + result = append(result, opcodes.NewHash) + result = append(result, common.IntToBytes(len(hash.Values))...) + return result +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-identifier.go b/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-identifier.go new file mode 100644 index 0000000..3322d3c --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-identifier.go @@ -0,0 +1,15 @@ +package assembler + +import ( + "github.com/shoriwe/gplasma/pkg/ast3" + "github.com/shoriwe/gplasma/pkg/bytecode/opcodes" + "github.com/shoriwe/gplasma/pkg/common" +) + +func (a *assembler) Identifier(ident *ast3.Identifier) []byte { + var result []byte + result = append(result, opcodes.Identifier) + result = append(result, common.IntToBytes(len(ident.Symbol))...) + result = append(result, []byte(ident.Symbol)...) + return result +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-index.go b/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-index.go new file mode 100644 index 0000000..e36d395 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-index.go @@ -0,0 +1,21 @@ +package assembler + +import ( + "github.com/shoriwe/gplasma/pkg/ast3" + magic_functions "github.com/shoriwe/gplasma/pkg/common/magic-functions" +) + +func (a *assembler) Index(index *ast3.Index) []byte { + return a.assemble(&ast3.Call{ + Expression: nil, + Function: &ast3.Selector{ + Assignable: nil, + X: index.Source, + Identifier: &ast3.Identifier{ + Assignable: nil, + Symbol: magic_functions.Get, + }, + }, + Arguments: []ast3.Expression{index.Index}, + }) +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-jump.go b/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-jump.go new file mode 100644 index 0000000..1b3e2bd --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-jump.go @@ -0,0 +1,32 @@ +package assembler + +import ( + "github.com/shoriwe/gplasma/pkg/ast3" + "github.com/shoriwe/gplasma/pkg/bytecode/opcodes" + "github.com/shoriwe/gplasma/pkg/common" +) + +func (a *assembler) Jump(jump *ast3.Jump) []byte { + result := []byte{opcodes.Jump} + result = append(result, common.IntToBytes(jump.Target.Code)...) + return result +} + +func (a *assembler) ContinueJump(jump *ast3.ContinueJump) []byte { + result := []byte{opcodes.Jump} + result = append(result, common.IntToBytes(jump.Target.Code)...) + return result +} + +func (a *assembler) BreakJump(jump *ast3.BreakJump) []byte { + result := []byte{opcodes.Jump} + result = append(result, common.IntToBytes(jump.Target.Code)...) + return result +} + +func (a *assembler) IfJump(jump *ast3.IfJump) []byte { + result := a.Expression(jump.Condition) + result = append(result, opcodes.Push, opcodes.IfJump) + result = append(result, common.IntToBytes(jump.Target.Code)...) + return result +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-label.go b/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-label.go new file mode 100644 index 0000000..1d7e87e --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-label.go @@ -0,0 +1,13 @@ +package assembler + +import ( + "github.com/shoriwe/gplasma/pkg/ast3" + "github.com/shoriwe/gplasma/pkg/bytecode/opcodes" + "github.com/shoriwe/gplasma/pkg/common" +) + +func (a *assembler) Label(label *ast3.Label) []byte { + result := []byte{opcodes.Label} + result = append(result, common.IntToBytes(label.Code)...) + return result +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-literals.go b/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-literals.go new file mode 100644 index 0000000..2045e9e --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-literals.go @@ -0,0 +1,49 @@ +package assembler + +import ( + "github.com/shoriwe/gplasma/pkg/ast3" + "github.com/shoriwe/gplasma/pkg/bytecode/opcodes" + "github.com/shoriwe/gplasma/pkg/common" +) + +func (a *assembler) Integer(integer *ast3.Integer) []byte { + var result []byte + result = append(result, opcodes.Integer) + result = append(result, common.IntToBytes(integer.Value)...) + return result +} + +func (a *assembler) Float(float *ast3.Float) []byte { + var result []byte + result = append(result, opcodes.Float) + result = append(result, common.FloatToBytes(float.Value)...) + return result +} + +func (a *assembler) String(s *ast3.String) []byte { + var result []byte + result = append(result, opcodes.String) + result = append(result, common.IntToBytes(len(s.Contents))...) + result = append(result, s.Contents...) + return result +} + +func (a *assembler) Bytes(bytes *ast3.Bytes) []byte { + var result []byte + result = append(result, opcodes.Bytes) + result = append(result, common.IntToBytes(len(bytes.Contents))...) + result = append(result, bytes.Contents...) + return result +} + +func (a *assembler) True(t *ast3.True) []byte { + return []byte{opcodes.True} +} + +func (a *assembler) False(f *ast3.False) []byte { + return []byte{opcodes.False} +} + +func (a *assembler) None(none *ast3.None) []byte { + return []byte{opcodes.None} +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-return-yield.go b/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-return-yield.go new file mode 100644 index 0000000..528f885 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-return-yield.go @@ -0,0 +1,18 @@ +package assembler + +import ( + "github.com/shoriwe/gplasma/pkg/ast3" + "github.com/shoriwe/gplasma/pkg/bytecode/opcodes" +) + +func (a *assembler) Return(ret *ast3.Return) []byte { + result := a.Expression(ret.Result) + result = append(result, opcodes.Push, opcodes.Return) + return result +} + +func (a *assembler) Yield(yield *ast3.Yield) []byte { + result := a.Expression(yield.Result) + result = append(result, opcodes.Push, opcodes.Return) + return result +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-selector.go b/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-selector.go new file mode 100644 index 0000000..fc00bca --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-selector.go @@ -0,0 +1,17 @@ +package assembler + +import ( + "github.com/shoriwe/gplasma/pkg/ast3" + "github.com/shoriwe/gplasma/pkg/bytecode/opcodes" + "github.com/shoriwe/gplasma/pkg/common" +) + +func (a *assembler) Selector(selector *ast3.Selector) []byte { + var result []byte + result = append(result, a.Expression(selector.X)...) + result = append(result, opcodes.Push) + result = append(result, opcodes.Selector) + result = append(result, common.IntToBytes(len(selector.Identifier.Symbol))...) + result = append(result, []byte(selector.Identifier.Symbol)...) + return result +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-statement.go b/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-statement.go new file mode 100644 index 0000000..694b200 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-statement.go @@ -0,0 +1,34 @@ +package assembler + +import ( + "fmt" + "github.com/shoriwe/gplasma/pkg/ast3" + "reflect" +) + +func (a *assembler) Statement(stmt ast3.Statement) []byte { + switch s := stmt.(type) { + case *ast3.Assignment: + return a.Assignment(s) + case *ast3.Label: + return a.Label(s) + case *ast3.Jump: + return a.Jump(s) + case *ast3.ContinueJump: + return a.ContinueJump(s) + case *ast3.BreakJump: + return a.BreakJump(s) + case *ast3.IfJump: + return a.IfJump(s) + case *ast3.Return: + return a.Return(s) + case *ast3.Yield: + return a.Yield(s) + case *ast3.Delete: + return a.Delete(s) + case *ast3.Defer: + return a.Defer(s) + default: + panic(fmt.Sprintf("unknown type of statement %s", reflect.TypeOf(s).String())) + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-super.go b/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-super.go new file mode 100644 index 0000000..2594de9 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-super.go @@ -0,0 +1,14 @@ +package assembler + +import ( + "github.com/shoriwe/gplasma/pkg/ast3" + "github.com/shoriwe/gplasma/pkg/bytecode/opcodes" +) + +func (a *assembler) Super(super *ast3.Super) []byte { + var result []byte + result = append(result, a.Expression(super.X)...) + result = append(result, opcodes.Push) + result = append(result, opcodes.Super) + return result +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-tuple.go b/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-tuple.go new file mode 100644 index 0000000..450821c --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble-tuple.go @@ -0,0 +1,18 @@ +package assembler + +import ( + "github.com/shoriwe/gplasma/pkg/ast3" + "github.com/shoriwe/gplasma/pkg/bytecode/opcodes" + "github.com/shoriwe/gplasma/pkg/common" +) + +func (a *assembler) Tuple(tuple *ast3.Tuple) []byte { + var result []byte + for _, value := range tuple.Values { + result = append(result, a.Expression(value)...) + result = append(result, opcodes.Push) + } + result = append(result, opcodes.NewTuple) + result = append(result, common.IntToBytes(len(tuple.Values))...) + return result +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble.go b/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble.go new file mode 100644 index 0000000..8df0d20 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/bytecode/assembler/assemble.go @@ -0,0 +1,275 @@ +package assembler + +import ( + "fmt" + "github.com/shoriwe/gplasma/pkg/ast3" + "github.com/shoriwe/gplasma/pkg/bytecode/opcodes" + "github.com/shoriwe/gplasma/pkg/common" + "reflect" +) + +type ( + assembler struct{} +) + +func newAssembler() *assembler { + return &assembler{} +} + +func (a *assembler) assemble(node ast3.Node) []byte { + if node == nil { + return nil + } + switch n := node.(type) { + case ast3.Statement: + return a.Statement(n) + case ast3.Expression: + return a.Expression(n) + default: + panic(fmt.Sprintf("unknown node type %s", reflect.TypeOf(n).String())) + } +} + +func (a *assembler) enumLabels(bytecode []byte) map[int64]int64 { + bytecodeLength := int64(len(bytecode)) + labels := map[int64]int64{} + for index := int64(0); index < bytecodeLength; { + op := bytecode[index] + switch op { + case opcodes.Push: + index++ + case opcodes.Pop: + index++ + case opcodes.IdentifierAssign: + index++ + symbolLength := common.BytesToInt(bytecode[index : index+8]) + index += 8 + symbolLength + case opcodes.SelectorAssign: + index++ + symbolLength := common.BytesToInt(bytecode[index : index+8]) + index += 8 + symbolLength + case opcodes.Label: + index++ + labelCode := common.BytesToInt(bytecode[index : index+8]) + labels[labelCode] = index - 1 + index += 8 + case opcodes.Jump: + index++ + index += 8 + case opcodes.IfJump: + index++ + index += 8 + case opcodes.Return: + index++ + case opcodes.DeleteIdentifier: + index++ + symbolLength := common.BytesToInt(bytecode[index : index+8]) + index += 8 + symbolLength + case opcodes.DeleteSelector: + index++ + symbolLength := common.BytesToInt(bytecode[index : index+8]) + index += 8 + symbolLength + case opcodes.Defer: + index++ + index += 8 + case opcodes.NewFunction: + index++ + argsNumber := common.BytesToInt(bytecode[index : index+8]) + index += 8 + for arg := int64(0); arg < argsNumber; arg++ { + argSymbolLength := common.BytesToInt(bytecode[index : index+8]) + index += 8 + argSymbolLength + } + index += 8 + case opcodes.NewClass: + index++ + index += 8 + index += 8 + case opcodes.Call: + index++ + index += 8 + case opcodes.NewArray: + index++ + index += 8 + case opcodes.NewTuple: + index++ + index += 8 + case opcodes.NewHash: + index++ + index += 8 + case opcodes.Identifier: + index++ + symbolLength := common.BytesToInt(bytecode[index : index+8]) + index += 8 + symbolLength + case opcodes.Integer: + index++ + index += 8 + case opcodes.Float: + index++ + index += 8 + case opcodes.String: + index++ + stringLength := common.BytesToInt(bytecode[index : index+8]) + index += 8 + stringLength + case opcodes.Bytes: + index++ + bytesLength := common.BytesToInt(bytecode[index : index+8]) + index += 8 + bytesLength + case opcodes.True: + index++ + case opcodes.False: + index++ + case opcodes.None: + index++ + case opcodes.Selector: + index++ + symbolLength := common.BytesToInt(bytecode[index : index+8]) + index += 8 + symbolLength + case opcodes.Super: + index++ + default: + panic(fmt.Sprintf("unknown opcode %d in %v", op, bytecode[index-5:])) + } + } + return labels +} + +func (a *assembler) resolveLabels(bytecode []byte, labels map[int64]int64) []byte { + bytecodeLength := int64(len(bytecode)) + for index := int64(0); index < bytecodeLength; { + op := bytecode[index] + switch op { + case opcodes.Push: + index++ + case opcodes.Pop: + index++ + case opcodes.IdentifierAssign: + index++ + symbolLength := common.BytesToInt(bytecode[index : index+8]) + index += 8 + symbolLength + case opcodes.SelectorAssign: + index++ + symbolLength := common.BytesToInt(bytecode[index : index+8]) + index += 8 + symbolLength + case opcodes.Label: + index++ + index += 8 + case opcodes.Jump: + labelCode := common.BytesToInt(bytecode[index+1 : index+9]) + jump := labels[labelCode] - index + index++ + copy(bytecode[index:index+8], common.IntToBytes(jump)) + index += 8 + case opcodes.IfJump: + labelCode := common.BytesToInt(bytecode[index+1 : index+9]) + jump := labels[labelCode] - index + index++ + copy(bytecode[index:index+8], common.IntToBytes(jump)) + index += 8 + case opcodes.Return: + index++ + case opcodes.DeleteIdentifier: + index++ + symbolLength := common.BytesToInt(bytecode[index : index+8]) + index += 8 + symbolLength + case opcodes.DeleteSelector: + index++ + symbolLength := common.BytesToInt(bytecode[index : index+8]) + index += 8 + symbolLength + case opcodes.Defer: + index++ + index += 8 + case opcodes.NewFunction: + index++ + argsNumber := common.BytesToInt(bytecode[index : index+8]) + index += 8 + for arg := int64(0); arg < argsNumber; arg++ { + argSymbolLength := common.BytesToInt(bytecode[index : index+8]) + index += 8 + argSymbolLength + } + index += 8 + case opcodes.NewClass: + index++ + index += 8 + index += 8 + case opcodes.Call: + index++ + index += 8 + case opcodes.NewArray: + index++ + index += 8 + case opcodes.NewTuple: + index++ + index += 8 + case opcodes.NewHash: + index++ + index += 8 + case opcodes.Identifier: + index++ + symbolLength := common.BytesToInt(bytecode[index : index+8]) + index += 8 + symbolLength + case opcodes.Integer: + index++ + index += 8 + case opcodes.Float: + index++ + index += 8 + case opcodes.String: + index++ + stringLength := common.BytesToInt(bytecode[index : index+8]) + index += 8 + stringLength + case opcodes.Bytes: + index++ + bytesLength := common.BytesToInt(bytecode[index : index+8]) + index += 8 + bytesLength + case opcodes.True: + index++ + case opcodes.False: + index++ + case opcodes.None: + index++ + case opcodes.Selector: + index++ + symbolLength := common.BytesToInt(bytecode[index : index+8]) + index += 8 + symbolLength + case opcodes.Super: + index++ + default: + panic(fmt.Sprintf("unknown opcode %d in %v", op, bytecode[index-5:])) + } + } + return bytecode +} + +func (a *assembler) Assemble(program ast3.Program) ([]byte, error) { + resultChan := make(chan []byte, 1) + errorChan := make(chan error, 1) + go func(rChan chan []byte, eChan chan error) { + defer func() { + err := recover() + if err != nil { + rChan <- nil + eChan <- err.(error) + } + }() + bytecode := make([]byte, 0, len(program)) + for _, node := range program { + chunk := a.assemble(node) + bytecode = append(bytecode, chunk...) + } + labels := a.enumLabels(bytecode) + rChan <- a.resolveLabels(bytecode, labels) + eChan <- nil + }(resultChan, errorChan) + return <-resultChan, <-errorChan +} + +func AssembleAny(node ast3.Node) ([]byte, error) { + a := newAssembler() + return a.Assemble(ast3.Program{node}) +} + +func Assemble(program ast3.Program) ([]byte, error) { + a := newAssembler() + return a.Assemble(program) +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/bytecode/opcodes/opcodes.go b/vendor/github.com/shoriwe/gplasma/pkg/bytecode/opcodes/opcodes.go new file mode 100644 index 0000000..fcfdedc --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/bytecode/opcodes/opcodes.go @@ -0,0 +1,61 @@ +package opcodes + +const ( + Push byte = iota + Pop + IdentifierAssign + SelectorAssign + Label + Jump + IfJump + Return + DeleteIdentifier + DeleteSelector + Defer + NewFunction + NewClass + Call + NewArray + NewTuple + NewHash + Identifier + Integer + Float + String + Bytes + True + False + None + Selector + Super +) + +var OpCodes = map[byte]string{ + Push: "Push", + Pop: "Pop", + IdentifierAssign: "IdentifierAssign", + SelectorAssign: "SelectorAssign", + Label: "Label", + Jump: "Jump", + IfJump: "IfJump", + Return: "Return", + DeleteIdentifier: "DeleteIdentifier", + DeleteSelector: "DeleteSelector", + Defer: "Defer", + NewFunction: "NewFunction", + NewClass: "NewClass", + Call: "Call", + NewArray: "NewArray", + NewTuple: "NewTuple", + NewHash: "NewHash", + Identifier: "Identifier", + Integer: "Integer", + Float: "Float", + String: "String", + Bytes: "Bytes", + True: "True", + False: "False", + None: "None", + Selector: "Selector", + Super: "Super", +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/common/list-stack.go b/vendor/github.com/shoriwe/gplasma/pkg/common/list-stack.go new file mode 100644 index 0000000..c183d4b --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/common/list-stack.go @@ -0,0 +1,32 @@ +package common + +type ( + stackNode struct { + Value any + Next *stackNode + } + ListStack[T any] struct { + Top *stackNode + } +) + +func (s *ListStack[T]) Push(value T) { + s.Top = &stackNode{ + Value: value, + Next: s.Top, + } +} + +func (s *ListStack[T]) Peek() T { + return s.Top.Value.(T) +} + +func (s *ListStack[T]) Pop() T { + value := s.Top.Value.(T) + s.Top = s.Top.Next + return value +} + +func (s *ListStack[T]) HasNext() bool { + return s.Top != nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/common/magic-functions/array.go b/vendor/github.com/shoriwe/gplasma/pkg/common/magic-functions/array.go new file mode 100644 index 0000000..79bce13 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/common/magic-functions/array.go @@ -0,0 +1,9 @@ +package magic_functions + +const ( + Append = "append" + Clear = "clear" + Pop = "pop" + Insert = "insert" + Remove = "remove" +) diff --git a/vendor/github.com/shoriwe/gplasma/pkg/common/magic-functions/int.go b/vendor/github.com/shoriwe/gplasma/pkg/common/magic-functions/int.go new file mode 100644 index 0000000..0cd0f1a --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/common/magic-functions/int.go @@ -0,0 +1,8 @@ +package magic_functions + +const ( + BigEndian = "big_endian" + LittleEndian = "little_endian" + FromBig = "from_big" + FromLittle = "from_little" +) diff --git a/vendor/github.com/shoriwe/gplasma/pkg/common/magic-functions/magic-functions.go b/vendor/github.com/shoriwe/gplasma/pkg/common/magic-functions/magic-functions.go new file mode 100644 index 0000000..a96527b --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/common/magic-functions/magic-functions.go @@ -0,0 +1,51 @@ +package magic_functions + +const ( + Init = "__init__" + HasNext = "__has_next__" + Next = "__next__" + Not = "__not__" + Positive = "__positive__" + Negative = "__negative__" + NegateBits = "__negate_bits__" + And = "__and__" + Or = "__or__" + Xor = "__xor__" + In = "__in__" + Is = "__is__" + Implements = "__implements__" + Equal = "__equal__" + NotEqual = "__not_equal__" + GreaterThan = "__greater_than__" + GreaterOrEqualThan = "__greater_or_equal_than__" + LessThan = "__less_than__" + LessOrEqualThan = "__less_or_equal_than__" + BitwiseOr = "__bitwise_or__" + BitwiseXor = "__bitwise_xor__" + BitwiseAnd = "__bitwise_and__" + BitwiseLeft = "__bitwise_left__" + BitwiseRight = "__bitwise_right__" + Add = "__add__" + Sub = "__sub__" + Mul = "__mul__" + Div = "__div__" + FloorDiv = "__floor_div__" + Modulus = "__mod__" + PowerOf = "__pow__" + Length = "__len__" + Bool = "__bool__" + String = "__string__" + Int = "__int__" + Float = "__float__" + Bytes = "__bytes__" + Array = "__array__" + Tuple = "__tuple__" + Get = "__get__" + Set = "__set__" + Del = "__del__" + Call = "__call__" + Class = "__class__" + SubClasses = "__sub_classes__" + Copy = "__copy__" + Iter = "__iter__" +) diff --git a/vendor/github.com/shoriwe/gplasma/pkg/common/magic-functions/string.go b/vendor/github.com/shoriwe/gplasma/pkg/common/magic-functions/string.go new file mode 100644 index 0000000..490cba3 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/common/magic-functions/string.go @@ -0,0 +1,10 @@ +package magic_functions + +const ( + Join = "join" + Split = "split" + Upper = "upper" + Lower = "lower" + Count = "count" + Index = "index" +) diff --git a/vendor/github.com/shoriwe/gplasma/pkg/common/map.go b/vendor/github.com/shoriwe/gplasma/pkg/common/map.go new file mode 100644 index 0000000..d4c3be2 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/common/map.go @@ -0,0 +1,13 @@ +package common + +type Hashable interface { + string | int | int8 | int16 | int32 | int64 | uint | uint8 | uint16 | uint32 | uint64 | float32 | float64 +} + +func CopyMap[T Hashable, Q any](m map[T]Q) map[T]Q { + result := make(map[T]Q, len(m)) + for key, value := range m { + result[key] = value + } + return result +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/common/numeric.go b/vendor/github.com/shoriwe/gplasma/pkg/common/numeric.go new file mode 100644 index 0000000..8859f8c --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/common/numeric.go @@ -0,0 +1,47 @@ +package common + +import ( + "encoding/binary" + "math" +) + +type ( + integer interface { + int | int8 | int16 | int32 | int64 + } + float interface { + float32 | float64 + } +) + +func IntToBytes[T integer](i T) []byte { + var bytes [8]byte + binary.BigEndian.PutUint64(bytes[:], uint64(i)) + return bytes[:] +} + +func BytesToInt(i []byte) int64 { + switch len(i) { + case 1: + return int64(i[0]) + case 2: + return int64(binary.BigEndian.Uint16(i)) + case 4: + return int64(binary.BigEndian.Uint32(i)) + case 8: + return int64(binary.BigEndian.Uint64(i)) + default: + panic("invalid integer length") + } +} + +func FloatToBytes[T float](f T) []byte { + var bytes [8]byte + u := math.Float64bits(float64(f)) + binary.BigEndian.PutUint64(bytes[:], u) + return bytes[:] +} + +func BytesToFloat(i []byte) float64 { + return math.Float64frombits(binary.BigEndian.Uint64(i)) +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/common/special-symbols/special-symbols.go b/vendor/github.com/shoriwe/gplasma/pkg/common/special-symbols/special-symbols.go new file mode 100644 index 0000000..ba0cb9c --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/common/special-symbols/special-symbols.go @@ -0,0 +1,21 @@ +package special_symbols + +const ( + Self = "self" + Value = "Value" + String = "String" + Bytes = "Bytes" + Bool = "Bool" + None = "None" + Int = "Int" + Float = "Float" + Array = "Array" + Tuple = "Tuple" + Hash = "Hash" + Function = "Function" + Class = "Class" + Input = "input" + Print = "print" + Println = "println" + Range = "range" +) diff --git a/vendor/github.com/shoriwe/gplasma/pkg/compiler/ast/expression.go b/vendor/github.com/shoriwe/gplasma/pkg/compiler/ast/expression.go deleted file mode 100644 index b3db006..0000000 --- a/vendor/github.com/shoriwe/gplasma/pkg/compiler/ast/expression.go +++ /dev/null @@ -1,663 +0,0 @@ -package ast - -import ( - "github.com/shoriwe/gplasma/pkg/compiler/lexer" - "github.com/shoriwe/gplasma/pkg/errors" - "github.com/shoriwe/gplasma/pkg/tools" - "github.com/shoriwe/gplasma/pkg/vm" - "strconv" - "strings" -) - -type IExpression interface { - Node - E() -} - -type ArrayExpression struct { - IExpression - Values []IExpression -} - -func (arrayExpression *ArrayExpression) Compile() ([]*vm.Code, *errors.Error) { - valuesLength := len(arrayExpression.Values) - var result []*vm.Code - for i := valuesLength - 1; i > -1; i-- { - childExpression, valueCompilationError := arrayExpression.Values[i].CompilePush(true) - if valueCompilationError != nil { - return nil, valueCompilationError - } - result = append(result, childExpression...) - } - return append(result, vm.NewCode(vm.NewArrayOP, errors.UnknownLine, len(arrayExpression.Values))), nil -} - -func (arrayExpression *ArrayExpression) CompilePush(push bool) ([]*vm.Code, *errors.Error) { - result, compilationError := arrayExpression.Compile() - if compilationError != nil { - return nil, compilationError - } - if push { - result = append(result, vm.NewCode(vm.PushOP, errors.UnknownLine, nil)) - } - return result, nil -} - -type TupleExpression struct { - IExpression - Values []IExpression -} - -func (tupleExpression *TupleExpression) Compile() ([]*vm.Code, *errors.Error) { - valuesLength := len(tupleExpression.Values) - var result []*vm.Code - for i := valuesLength - 1; i > -1; i-- { - childExpression, valueCompilationError := tupleExpression.Values[i].CompilePush(true) - if valueCompilationError != nil { - return nil, valueCompilationError - } - result = append(result, childExpression...) - } - return append(result, vm.NewCode(vm.NewTupleOP, errors.UnknownLine, len(tupleExpression.Values))), nil -} - -func (tupleExpression *TupleExpression) CompilePush(push bool) ([]*vm.Code, *errors.Error) { - result, compilationError := tupleExpression.Compile() - if compilationError != nil { - return nil, compilationError - } - if push { - result = append(result, vm.NewCode(vm.PushOP, errors.UnknownLine, nil)) - } - return result, nil -} - -type KeyValue struct { - Key IExpression - Value IExpression -} - -type HashExpression struct { - IExpression - Values []*KeyValue -} - -func (hashExpression *HashExpression) CompilePush(push bool) ([]*vm.Code, *errors.Error) { - result, compilationError := hashExpression.Compile() - if compilationError != nil { - return nil, compilationError - } - if push { - result = append(result, vm.NewCode(vm.PushOP, errors.UnknownLine, nil)) - } - return result, nil -} - -func (hashExpression *HashExpression) Compile() ([]*vm.Code, *errors.Error) { - valuesLength := len(hashExpression.Values) - var result []*vm.Code - for i := valuesLength - 1; i > -1; i-- { - key, valueCompilationError := hashExpression.Values[i].Value.CompilePush(true) - if valueCompilationError != nil { - return nil, valueCompilationError - } - result = append(result, key...) - value, keyCompilationError := hashExpression.Values[i].Key.CompilePush(true) - if keyCompilationError != nil { - return nil, keyCompilationError - } - result = append(result, value...) - } - return append(result, vm.NewCode(vm.NewHashOP, errors.UnknownLine, len(hashExpression.Values))), nil -} - -type Identifier struct { - IExpression - Token *lexer.Token -} - -func (identifier *Identifier) CompilePush(push bool) ([]*vm.Code, *errors.Error) { - result, compilationError := identifier.Compile() - if compilationError != nil { - return nil, compilationError - } - if push { - result = append(result, vm.NewCode(vm.PushOP, errors.UnknownLine, nil)) - } - return result, nil -} - -func (identifier *Identifier) Compile() ([]*vm.Code, *errors.Error) { - return []*vm.Code{vm.NewCode(vm.GetIdentifierOP, identifier.Token.Line, identifier.Token.String)}, nil -} - -type BasicLiteralExpression struct { - IExpression - Token *lexer.Token - Kind uint8 - DirectValue uint8 -} - -func (basicLiteral *BasicLiteralExpression) CompilePush(push bool) ([]*vm.Code, *errors.Error) { - result, compilationError := basicLiteral.Compile() - if compilationError != nil { - return nil, compilationError - } - if push { - result = append(result, vm.NewCode(vm.PushOP, errors.UnknownLine, nil)) - } - return result, nil -} - -func (basicLiteral *BasicLiteralExpression) Compile() ([]*vm.Code, *errors.Error) { - switch basicLiteral.DirectValue { - case lexer.Integer: - numberString := basicLiteral.Token.String - numberString = strings.ReplaceAll(numberString, "_", "") - number, success := strconv.ParseInt(numberString, 10, 64) - if success != nil { - return nil, errors.New(basicLiteral.Token.Line, "Error parsing Integer", errors.GoRuntimeError) - } - return []*vm.Code{vm.NewCode(vm.NewIntegerOP, basicLiteral.Token.Line, number)}, nil - case lexer.HexadecimalInteger: - numberString := basicLiteral.Token.String - numberString = strings.ReplaceAll(numberString, "_", "") - numberString = numberString[2:] - number, parsingError := strconv.ParseInt(numberString, 16, 64) - if parsingError != nil { - return nil, errors.New(basicLiteral.Token.Line, "Error parsing Hexadecimal Integer", errors.GoRuntimeError) - } - return []*vm.Code{vm.NewCode(vm.NewIntegerOP, basicLiteral.Token.Line, number)}, nil - case lexer.OctalInteger: - numberString := basicLiteral.Token.String - numberString = strings.ReplaceAll(numberString, "_", "") - numberString = numberString[2:] - number, parsingError := strconv.ParseInt(numberString, 8, 64) - if parsingError != nil { - return nil, errors.New(basicLiteral.Token.Line, "Error parsing Octal Integer", errors.GoRuntimeError) - } - return []*vm.Code{vm.NewCode(vm.NewIntegerOP, basicLiteral.Token.Line, number)}, nil - case lexer.BinaryInteger: - numberString := basicLiteral.Token.String - numberString = strings.ReplaceAll(numberString, "_", "") - numberString = numberString[2:] - number, parsingError := strconv.ParseInt(numberString, 2, 64) - if parsingError != nil { - return nil, errors.New(basicLiteral.Token.Line, "Error parsing Binary Integer", errors.GoRuntimeError) - } - return []*vm.Code{vm.NewCode(vm.NewIntegerOP, basicLiteral.Token.Line, number)}, nil - case lexer.Float, lexer.ScientificFloat: - numberString := basicLiteral.Token.String - numberString = strings.ReplaceAll(numberString, "_", "") - number, parsingError := strconv.ParseFloat(numberString, 64) - if parsingError != nil { - return nil, errors.New(basicLiteral.Token.Line, parsingError.Error(), errors.GoRuntimeError) - } - return []*vm.Code{vm.NewCode(vm.NewFloatOP, basicLiteral.Token.Line, number)}, nil - case lexer.SingleQuoteString, lexer.DoubleQuoteString: - return []*vm.Code{vm.NewCode( - vm.NewStringOP, basicLiteral.Token.Line, - - string( - tools.ReplaceEscaped( - []rune(basicLiteral.Token.String[1:len(basicLiteral.Token.String)-1])), - ), - ), - }, nil - case lexer.ByteString: - return []*vm.Code{vm.NewCode(vm.NewBytesOP, basicLiteral.Token.Line, - []byte( - string( - tools.ReplaceEscaped( - []rune(basicLiteral.Token.String[2:len(basicLiteral.Token.String)-1]), - ), - ), - ), - ), - }, nil - case lexer.True: - return []*vm.Code{vm.NewCode(vm.GetTrueOP, basicLiteral.Token.Line, nil)}, nil - case lexer.False: - return []*vm.Code{vm.NewCode(vm.GetFalseOP, basicLiteral.Token.Line, nil)}, nil - case lexer.None: - return []*vm.Code{vm.NewCode(vm.GetNoneOP, basicLiteral.Token.Line, nil)}, nil - } - panic(errors.NewUnknownVMOperationError(basicLiteral.Token.DirectValue)) -} - -type BinaryExpression struct { - IExpression - LeftHandSide IExpression - Operator *lexer.Token - RightHandSide IExpression -} - -func (binaryExpression *BinaryExpression) CompilePush(push bool) ([]*vm.Code, *errors.Error) { - result, compilationError := binaryExpression.Compile() - if compilationError != nil { - return nil, compilationError - } - if push { - result = append(result, vm.NewCode(vm.PushOP, errors.UnknownLine, nil)) - } - return result, nil -} - -func (binaryExpression *BinaryExpression) Compile() ([]*vm.Code, *errors.Error) { - var result []*vm.Code - // CompilePush first right hand side - right, rightHandSideCompileError := binaryExpression.RightHandSide.CompilePush(true) - if rightHandSideCompileError != nil { - return nil, rightHandSideCompileError - } - result = append(result, right...) - // Then left hand side - left, leftHandSideCompileError := binaryExpression.LeftHandSide.CompilePush(true) - if leftHandSideCompileError != nil { - return nil, leftHandSideCompileError - } - result = append(result, left...) - var operation uint8 - // Finally decide the instruction to use - switch binaryExpression.Operator.DirectValue { - case lexer.Add: - operation = vm.AddOP - case lexer.Sub: - operation = vm.SubOP - case lexer.Star: - operation = vm.MulOP - case lexer.Div: - operation = vm.DivOP - case lexer.FloorDiv: - operation = vm.FloorDivOP - case lexer.Modulus: - operation = vm.ModOP - case lexer.PowerOf: - operation = vm.PowOP - case lexer.BitwiseXor: - operation = vm.BitXorOP - case lexer.BitWiseAnd: - operation = vm.BitAndOP - case lexer.BitwiseOr: - operation = vm.BitOrOP - case lexer.BitwiseLeft: - operation = vm.BitLeftOP - case lexer.BitwiseRight: - operation = vm.BitRightOP - case lexer.And: - operation = vm.AndOP - case lexer.Or: - operation = vm.OrOP - case lexer.Xor: - operation = vm.XorOP - case lexer.Equals: - operation = vm.EqualsOP - case lexer.NotEqual: - operation = vm.NotEqualsOP - case lexer.GreaterThan: - operation = vm.GreaterThanOP - case lexer.LessThan: - operation = vm.LessThanOP - case lexer.GreaterOrEqualThan: - operation = vm.GreaterThanOrEqualOP - case lexer.LessOrEqualThan: - operation = vm.LessThanOrEqualOP - case lexer.In: - operation = vm.ContainsOP - default: - panic(errors.NewUnknownVMOperationError(binaryExpression.Operator.DirectValue)) - } - result = append(result, vm.NewCode(vm.BinaryOP, binaryExpression.Operator.Line, operation)) - return result, nil -} - -type UnaryExpression struct { - IExpression - Operator *lexer.Token - X IExpression -} - -func (unaryExpression *UnaryExpression) CompilePush(push bool) ([]*vm.Code, *errors.Error) { - result, compilationError := unaryExpression.Compile() - if compilationError != nil { - return nil, compilationError - } - if push { - result = append(result, vm.NewCode(vm.PushOP, errors.UnknownLine, nil)) - } - return result, nil -} - -func (unaryExpression *UnaryExpression) Compile() ([]*vm.Code, *errors.Error) { - result, expressionCompileError := unaryExpression.X.CompilePush(true) - if expressionCompileError != nil { - return nil, expressionCompileError - } - switch unaryExpression.Operator.DirectValue { - case lexer.NegateBits: - result = append(result, vm.NewCode(vm.UnaryOP, unaryExpression.Operator.Line, vm.NegateBitsOP)) - case lexer.Not, lexer.SignNot: - result = append(result, vm.NewCode(vm.UnaryOP, unaryExpression.Operator.Line, vm.BoolNegateOP)) - case lexer.Sub: - result = append(result, vm.NewCode(vm.UnaryOP, unaryExpression.Operator.Line, vm.NegativeOP)) - } - return result, nil -} - -type ParenthesesExpression struct { - IExpression - X IExpression -} - -func (parenthesesExpression *ParenthesesExpression) CompilePush(push bool) ([]*vm.Code, *errors.Error) { - result, compilationError := parenthesesExpression.Compile() - if compilationError != nil { - return nil, compilationError - } - if push { - result = append(result, vm.NewCode(vm.PushOP, errors.UnknownLine, nil)) - } - return result, nil -} - -func (parenthesesExpression *ParenthesesExpression) Compile() ([]*vm.Code, *errors.Error) { - return parenthesesExpression.X.CompilePush(false) -} - -type LambdaExpression struct { - IExpression - Arguments []*Identifier - Code IExpression -} - -func (lambdaExpression *LambdaExpression) CompilePush(push bool) ([]*vm.Code, *errors.Error) { - result, compilationError := lambdaExpression.Compile() - if compilationError != nil { - return nil, compilationError - } - if push { - result = append(result, vm.NewCode(vm.PushOP, errors.UnknownLine, nil)) - } - return result, nil -} - -func (lambdaExpression *LambdaExpression) Compile() ([]*vm.Code, *errors.Error) { - functionCode, lambdaCodeCompilationError := lambdaExpression.Code.CompilePush(true) - if lambdaCodeCompilationError != nil { - return nil, lambdaCodeCompilationError - } - var arguments []string - for _, argument := range lambdaExpression.Arguments { - arguments = append(arguments, argument.Token.String) - } - functionBody := []*vm.Code{vm.NewCode(vm.LoadFunctionArgumentsOP, errors.UnknownLine, arguments)} - functionBody = append(functionBody, functionCode...) - functionBody = append(functionBody, vm.NewCode(vm.ReturnOP, errors.UnknownLine, 1)) - var result []*vm.Code - result = append(result, - vm.NewCode( - vm.NewFunctionOP, - errors.UnknownLine, - vm.FunctionInformation{ - Name: "", - Body: functionBody, - NumberOfArguments: len(arguments), - }, - ), - ) - return result, nil -} - -type GeneratorExpression struct { - IExpression - Operation IExpression - Receivers []*Identifier - Source IExpression -} - -func (generatorExpression *GeneratorExpression) CompilePush(push bool) ([]*vm.Code, *errors.Error) { - result, compilationError := generatorExpression.Compile() - if compilationError != nil { - return nil, compilationError - } - if push { - result = append(result, vm.NewCode(vm.PushOP, errors.UnknownLine, nil)) - } - return result, nil -} - -func (generatorExpression *GeneratorExpression) Compile() ([]*vm.Code, *errors.Error) { - source, sourceCompilationError := generatorExpression.Source.CompilePush(true) - if sourceCompilationError != nil { - return nil, sourceCompilationError - } - operationAsLambda := &LambdaExpression{ - Arguments: generatorExpression.Receivers, - Code: generatorExpression.Operation, - } - operation, operationCompilationError := operationAsLambda.CompilePush(true) - if operationCompilationError != nil { - return nil, operationCompilationError - } - - var result []*vm.Code - result = append(result, source...) - result = append(result, operation...) - result = append(result, - vm.NewCode(vm.NewGeneratorOP, errors.UnknownLine, len(generatorExpression.Receivers)), - ) - return result, nil -} - -type SelectorExpression struct { - IExpression - X IExpression - Identifier *Identifier -} - -func (selectorExpression *SelectorExpression) CompilePush(push bool) ([]*vm.Code, *errors.Error) { - result, compilationError := selectorExpression.Compile() - if compilationError != nil { - return nil, compilationError - } - if push { - result = append(result, vm.NewCode(vm.PushOP, errors.UnknownLine, nil)) - } - return result, nil -} - -func (selectorExpression *SelectorExpression) Compile() ([]*vm.Code, *errors.Error) { - source, sourceCompilationError := selectorExpression.X.CompilePush(true) - if sourceCompilationError != nil { - return nil, sourceCompilationError - } - return append(source, vm.NewCode(vm.SelectNameFromObjectOP, selectorExpression.Identifier.Token.Line, selectorExpression.Identifier.Token.String)), nil -} - -type MethodInvocationExpression struct { - IExpression - Function IExpression - Arguments []IExpression -} - -func (methodInvocationExpression *MethodInvocationExpression) CompilePush(push bool) ([]*vm.Code, *errors.Error) { - result, compilationError := methodInvocationExpression.Compile() - if compilationError != nil { - return nil, compilationError - } - if push { - result = append(result, vm.NewCode(vm.PushOP, errors.UnknownLine, nil)) - } - return result, nil -} - -func (methodInvocationExpression *MethodInvocationExpression) Compile() ([]*vm.Code, *errors.Error) { - numberOfArguments := len(methodInvocationExpression.Arguments) - var result []*vm.Code - for i := numberOfArguments - 1; i > -1; i-- { - argument, argumentCompilationError := methodInvocationExpression.Arguments[i].CompilePush(true) - if argumentCompilationError != nil { - return nil, argumentCompilationError - } - result = append(result, argument...) - } - function, functionCompilationError := methodInvocationExpression.Function.CompilePush(true) - if functionCompilationError != nil { - return nil, functionCompilationError - } - result = append(result, function...) - return append(result, vm.NewCode(vm.MethodInvocationOP, errors.UnknownLine, len(methodInvocationExpression.Arguments))), nil -} - -type IndexExpression struct { - IExpression - Source IExpression - Index IExpression -} - -func (indexExpression *IndexExpression) CompilePush(push bool) ([]*vm.Code, *errors.Error) { - result, compilationError := indexExpression.Compile() - if compilationError != nil { - return nil, compilationError - } - if push { - result = append(result, vm.NewCode(vm.PushOP, errors.UnknownLine, nil)) - } - return result, nil -} - -func (indexExpression *IndexExpression) Compile() ([]*vm.Code, *errors.Error) { - source, sourceCompilationError := indexExpression.Source.CompilePush(true) - if sourceCompilationError != nil { - return nil, sourceCompilationError - } - index, indexCompilationError := indexExpression.Index.CompilePush(true) - if indexCompilationError != nil { - return nil, indexCompilationError - } - result := source - result = append(result, index...) - return append(result, vm.NewCode(vm.IndexOP, errors.UnknownLine, nil)), nil -} - -type IfOneLinerExpression struct { - IExpression - Result IExpression - Condition IExpression - ElseResult IExpression -} - -func (ifOneLinerExpression *IfOneLinerExpression) CompilePush(push bool) ([]*vm.Code, *errors.Error) { - result, compilationError := ifOneLinerExpression.Compile() - if compilationError != nil { - return nil, compilationError - } - if push { - result = append(result, vm.NewCode(vm.PushOP, errors.UnknownLine, nil)) - } - return result, nil -} - -func (ifOneLinerExpression *IfOneLinerExpression) Compile() ([]*vm.Code, *errors.Error) { - condition, conditionCompilationError := ifOneLinerExpression.Condition.CompilePush(true) - if conditionCompilationError != nil { - return nil, conditionCompilationError - } - ifReturnResult := &ReturnStatement{ - Results: []IExpression{ifOneLinerExpression.Result}, - } - ifResult, ifResultCompilationError := ifReturnResult.Compile() - if ifResultCompilationError != nil { - return nil, ifResultCompilationError - } - var elseResult []*vm.Code - if ifOneLinerExpression.ElseResult != nil { - elseReturnResult := &ReturnStatement{ - Results: []IExpression{ifOneLinerExpression.ElseResult}, - } - var elseResultCompilationError *errors.Error - elseResult, elseResultCompilationError = elseReturnResult.Compile() - if elseResultCompilationError != nil { - return nil, elseResultCompilationError - } - } else { - elseResult = []*vm.Code{ - vm.NewCode(vm.GetNoneOP, errors.UnknownLine, nil), - vm.NewCode(vm.PushOP, errors.UnknownLine, nil), - vm.NewCode(vm.ReturnOP, errors.UnknownLine, 1), - } - } - var result []*vm.Code - result = append(result, condition...) - result = append(result, - vm.NewCode(vm.IfOneLinerOP, - errors.UnknownLine, - vm.ConditionInformation{ - Body: ifResult, - ElseBody: elseResult, - }, - ), - ) - return result, nil -} - -type UnlessOneLinerExpression struct { - IExpression - Result IExpression - Condition IExpression - ElseResult IExpression -} - -func (unlessOneLinerExpression *UnlessOneLinerExpression) CompilePush(push bool) ([]*vm.Code, *errors.Error) { - result, compilationError := unlessOneLinerExpression.Compile() - if compilationError != nil { - return nil, compilationError - } - if push { - result = append(result, vm.NewCode(vm.PushOP, errors.UnknownLine, nil)) - } - return result, nil -} - -func (unlessOneLinerExpression *UnlessOneLinerExpression) Compile() ([]*vm.Code, *errors.Error) { - condition, conditionCompilationError := unlessOneLinerExpression.Condition.CompilePush(true) - if conditionCompilationError != nil { - return nil, conditionCompilationError - } - ifReturnResult := &ReturnStatement{ - Results: []IExpression{unlessOneLinerExpression.Result}, - } - ifResult, ifResultCompilationError := ifReturnResult.Compile() - if ifResultCompilationError != nil { - return nil, ifResultCompilationError - } - var elseResult []*vm.Code - if unlessOneLinerExpression.ElseResult != nil { - elseReturnResult := &ReturnStatement{ - Results: []IExpression{unlessOneLinerExpression.ElseResult}, - } - var elseResultCompilationError *errors.Error - elseResult, elseResultCompilationError = elseReturnResult.Compile() - if elseResultCompilationError != nil { - return nil, elseResultCompilationError - } - } else { - elseResult = []*vm.Code{ - vm.NewCode(vm.GetNoneOP, errors.UnknownLine, nil), - vm.NewCode(vm.PushOP, errors.UnknownLine, nil), - vm.NewCode(vm.ReturnOP, errors.UnknownLine, 1), - } - } - var result []*vm.Code - result = append(result, condition...) - result = append(result, - vm.NewCode(vm.UnlessOneLinerOP, - errors.UnknownLine, - vm.ConditionInformation{ - Body: ifResult, - ElseBody: elseResult, - }, - ), - ) - return result, nil -} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/compiler/ast/node.go b/vendor/github.com/shoriwe/gplasma/pkg/compiler/ast/node.go deleted file mode 100644 index 94bce66..0000000 --- a/vendor/github.com/shoriwe/gplasma/pkg/compiler/ast/node.go +++ /dev/null @@ -1,54 +0,0 @@ -package ast - -import ( - "github.com/shoriwe/gplasma/pkg/errors" - "github.com/shoriwe/gplasma/pkg/vm" -) - -type Node interface { - Compile() ([]*vm.Code, *errors.Error) - CompilePush(push bool) ([]*vm.Code, *errors.Error) -} - -func compileBody(body []Node) ([]*vm.Code, *errors.Error) { - var result []*vm.Code - for _, node := range body { - nodeCode, compileError := node.Compile() - if compileError != nil { - return nil, compileError - } - result = append(result, nodeCode...) - } - return result, nil -} - -type Program struct { - Node - Begin *BeginStatement - End *EndStatement - Body []Node -} - -func (program *Program) Compile() ([]*vm.Code, *errors.Error) { - var result []*vm.Code - if program.Begin != nil { - beginBody, beginCompilationError := program.Begin.Compile() - if beginCompilationError != nil { - return nil, beginCompilationError - } - result = append(result, beginBody...) - } - body, bodyCompilationError := compileBody(program.Body) - if bodyCompilationError != nil { - return nil, bodyCompilationError - } - result = append(result, body...) - if program.End != nil { - endBody, endCompilationError := program.End.Compile() - if endCompilationError != nil { - return nil, endCompilationError - } - result = append(result, endBody...) - } - return result, nil -} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/compiler/ast/statement.go b/vendor/github.com/shoriwe/gplasma/pkg/compiler/ast/statement.go deleted file mode 100644 index 615d829..0000000 --- a/vendor/github.com/shoriwe/gplasma/pkg/compiler/ast/statement.go +++ /dev/null @@ -1,772 +0,0 @@ -package ast - -import ( - "github.com/shoriwe/gplasma/pkg/compiler/lexer" - "github.com/shoriwe/gplasma/pkg/errors" - "github.com/shoriwe/gplasma/pkg/vm" - "reflect" -) - -type Statement interface { - S() - Node -} - -func compileClassBody(body []Node) ([]*vm.Code, *errors.Error) { - foundInitialize := false - var isInitialize bool - var nodeCode []*vm.Code - var compilationError *errors.Error - var result []*vm.Code - for _, node := range body { - switch node.(type) { - case IExpression: - nodeCode, compilationError = node.(IExpression).CompilePush(true) - case Statement: - if _, ok := node.(*FunctionDefinitionStatement); ok { - nodeCode, compilationError, isInitialize = node.(*FunctionDefinitionStatement).CompileAsClassFunction() - if isInitialize && !foundInitialize { - foundInitialize = true - } - } else { - nodeCode, compilationError = node.(Statement).Compile() - } - } - if compilationError != nil { - return nil, compilationError - } - result = append(result, nodeCode...) - } - if !foundInitialize { - initFunction := &FunctionDefinitionStatement{ - Name: &Identifier{ - Token: &lexer.Token{ - String: vm.Initialize, - }, - }, - Arguments: nil, - Body: nil, - } - nodeCode, _, _ = initFunction.CompileAsClassFunction() - result = append(result, nodeCode...) - } - return result, nil -} - -type AssignStatement struct { - Statement - LeftHandSide IExpression // Identifiers or Selectors - AssignOperator *lexer.Token - RightHandSide IExpression -} - -func compileAssignStatementMiddleBinaryExpression(leftHandSide IExpression, assignOperator *lexer.Token) ([]*vm.Code, *errors.Error) { - result, leftHandSideCompilationError := leftHandSide.CompilePush(true) - if leftHandSideCompilationError != nil { - return nil, leftHandSideCompilationError - } - // Finally decide the instruction to use - var operation uint8 - switch assignOperator.DirectValue { - case lexer.AddAssign: - operation = vm.AddOP - case lexer.SubAssign: - operation = vm.SubOP - case lexer.StarAssign: - operation = vm.MulOP - case lexer.DivAssign: - operation = vm.DivOP - case lexer.ModulusAssign: - operation = vm.ModOP - case lexer.PowerOfAssign: - operation = vm.PowOP - case lexer.BitwiseXorAssign: - operation = vm.BitXorOP - case lexer.BitWiseAndAssign: - operation = vm.BitAndOP - case lexer.BitwiseOrAssign: - operation = vm.BitOrOP - case lexer.BitwiseLeftAssign: - operation = vm.BitLeftOP - case lexer.BitwiseRightAssign: - operation = vm.BitRightOP - default: - panic(errors.NewUnknownVMOperationError(operation)) - } - return append(result, vm.NewCode(vm.BinaryOP, assignOperator.Line, operation)), nil -} - -func compileIdentifierAssign(identifier *Identifier) ([]*vm.Code, *errors.Error) { - return []*vm.Code{vm.NewCode(vm.AssignIdentifierOP, identifier.Token.Line, identifier.Token.String)}, nil -} - -func compileSelectorAssign(selectorExpression *SelectorExpression) ([]*vm.Code, *errors.Error) { - result, sourceCompilationError := selectorExpression.X.CompilePush(true) - if sourceCompilationError != nil { - return nil, sourceCompilationError - } - return append(result, vm.NewCode(vm.AssignSelectorOP, selectorExpression.Identifier.Token.Line, selectorExpression.Identifier.Token.String)), nil -} - -func compileIndexAssign(indexExpression *IndexExpression) ([]*vm.Code, *errors.Error) { - result, sourceCompilationError := indexExpression.Source.CompilePush(true) - if sourceCompilationError != nil { - return nil, sourceCompilationError - } - index, indexCompilationError := indexExpression.Index.CompilePush(true) - if indexCompilationError != nil { - return nil, indexCompilationError - } - result = append(result, index...) - return append(result, vm.NewCode(vm.AssignIndexOP, errors.UnknownLine, nil)), nil -} - -func (assignStatement *AssignStatement) Compile() ([]*vm.Code, *errors.Error) { - result, valueCompilationError := assignStatement.RightHandSide.CompilePush(true) - if valueCompilationError != nil { - return nil, valueCompilationError - } - if assignStatement.AssignOperator.DirectValue != lexer.Assign { - // Do something here to evaluate the operation - assignOperation, middleOperationCompilationError := compileAssignStatementMiddleBinaryExpression(assignStatement.LeftHandSide, assignStatement.AssignOperator) - if middleOperationCompilationError != nil { - return nil, middleOperationCompilationError - } - result = append(result, assignOperation...) - result = append(result, vm.NewCode(vm.PushOP, errors.UnknownLine, nil)) - } - var leftHandSide []*vm.Code - var leftHandSideCompilationError *errors.Error - switch assignStatement.LeftHandSide.(type) { - case *Identifier: - leftHandSide, leftHandSideCompilationError = compileIdentifierAssign(assignStatement.LeftHandSide.(*Identifier)) - case *SelectorExpression: - leftHandSide, leftHandSideCompilationError = compileSelectorAssign(assignStatement.LeftHandSide.(*SelectorExpression)) - case *IndexExpression: - leftHandSide, leftHandSideCompilationError = compileIndexAssign(assignStatement.LeftHandSide.(*IndexExpression)) - default: - panic(reflect.TypeOf(assignStatement.LeftHandSide)) - } - if leftHandSideCompilationError != nil { - return nil, leftHandSideCompilationError - } - return append(result, leftHandSide...), nil -} - -type DoWhileStatement struct { - Statement - Condition IExpression - Body []Node -} - -func (doWhileStatement *DoWhileStatement) Compile() ([]*vm.Code, *errors.Error) { - conditionReturn := &ReturnStatement{ - Results: []IExpression{doWhileStatement.Condition}, - } - condition, conditionCompilationError := conditionReturn.Compile() - if conditionCompilationError != nil { - return nil, conditionCompilationError - } - body, bodyCompilationError := compileBody(doWhileStatement.Body) - if bodyCompilationError != nil { - return nil, bodyCompilationError - } - var result []*vm.Code - result = append(result, - vm.NewCode(vm.DoWhileLoopOP, errors.UnknownLine, - vm.LoopInformation{ - Body: body, - Condition: condition, - Receivers: nil, - }, - ), - ) - - return result, nil -} - -type WhileLoopStatement struct { - Statement - Condition IExpression - Body []Node -} - -func (whileStatement *WhileLoopStatement) Compile() ([]*vm.Code, *errors.Error) { - conditionReturn := &ReturnStatement{ - Results: []IExpression{whileStatement.Condition}, - } - condition, conditionCompilationError := conditionReturn.Compile() - if conditionCompilationError != nil { - return nil, conditionCompilationError - } - body, bodyCompilationError := compileBody(whileStatement.Body) - if bodyCompilationError != nil { - return nil, bodyCompilationError - } - var result []*vm.Code - result = append(result, - vm.NewCode(vm.WhileLoopOP, errors.UnknownLine, - vm.LoopInformation{ - Body: body, - Condition: condition, - Receivers: nil, - }, - ), - ) - return result, nil -} - -type UntilLoopStatement struct { - Statement - Condition IExpression - Body []Node -} - -func (untilLoop *UntilLoopStatement) Compile() ([]*vm.Code, *errors.Error) { - conditionReturn := &ReturnStatement{ - Results: []IExpression{untilLoop.Condition}, - } - condition, conditionCompilationError := conditionReturn.Compile() - if conditionCompilationError != nil { - return nil, conditionCompilationError - } - body, bodyCompilationError := compileBody(untilLoop.Body) - if bodyCompilationError != nil { - return nil, bodyCompilationError - } - var result []*vm.Code - result = append(result, - vm.NewCode(vm.UntilLoopOP, errors.UnknownLine, - vm.LoopInformation{ - Body: body, - Condition: condition, - Receivers: nil, - }, - ), - ) - return result, nil -} - -type ForLoopStatement struct { - Statement - Receivers []*Identifier - Source IExpression - Body []Node -} - -func (forStatement *ForLoopStatement) Compile() ([]*vm.Code, *errors.Error) { - source, compilationError := forStatement.Source.CompilePush(true) - if compilationError != nil { - return nil, compilationError - } - body, bodyCompilationError := compileBody(forStatement.Body) - if bodyCompilationError != nil { - return nil, bodyCompilationError - } - var receivers []string - for _, receiver := range forStatement.Receivers { - receivers = append( - receivers, - receiver.Token.String, - ) - } - var result []*vm.Code - result = append(result, source...) - result = append( - result, - vm.NewCode( - vm.ForLoopOP, - errors.UnknownLine, - vm.LoopInformation{ - Body: body, - Condition: nil, - Receivers: receivers, - }, - ), - ) - return result, nil -} - -type IfStatement struct { - Statement - Condition IExpression - Body []Node - Else []Node -} - -func (ifStatement *IfStatement) Compile() ([]*vm.Code, *errors.Error) { - condition, conditionCompilationError := ifStatement.Condition.CompilePush(true) - if conditionCompilationError != nil { - return nil, conditionCompilationError - } - body, bodyCompilationError := compileBody(ifStatement.Body) - if bodyCompilationError != nil { - return nil, bodyCompilationError - } - var elseBody []*vm.Code - if ifStatement.Else != nil { - var elseBodyCompilationError *errors.Error - elseBody, elseBodyCompilationError = compileBody(ifStatement.Else) - if elseBodyCompilationError != nil { - return nil, elseBodyCompilationError - } - } - var result []*vm.Code - result = append(result, condition...) - result = append(result, - vm.NewCode(vm.IfOP, errors.UnknownLine, - vm.ConditionInformation{ - Body: body, - ElseBody: elseBody, - }, - ), - ) - return result, nil -} - -type UnlessStatement struct { - Statement - Condition IExpression - Body []Node - Else []Node -} - -func (unlessStatement *UnlessStatement) Compile() ([]*vm.Code, *errors.Error) { - condition, conditionCompilationError := unlessStatement.Condition.CompilePush(true) - if conditionCompilationError != nil { - return nil, conditionCompilationError - } - body, bodyCompilationError := compileBody(unlessStatement.Body) - if bodyCompilationError != nil { - return nil, bodyCompilationError - } - var elseBody []*vm.Code - if unlessStatement.Body != nil { - var elseBodyCompilationError *errors.Error - elseBody, elseBodyCompilationError = compileBody(unlessStatement.Else) - if elseBodyCompilationError != nil { - return nil, elseBodyCompilationError - } - } - var result []*vm.Code - result = append(result, condition...) - result = append(result, - vm.NewCode(vm.UnlessOP, errors.UnknownLine, - vm.ConditionInformation{ - Body: body, - ElseBody: elseBody, - }, - ), - ) - return result, nil -} - -type CaseBlock struct { - Cases []IExpression - Body []Node -} - -type SwitchStatement struct { - Statement - Target IExpression - CaseBlocks []*CaseBlock - Default []Node -} - -func (switchStatement *SwitchStatement) Compile() ([]*vm.Code, *errors.Error) { - reference, referenceCompilationError := switchStatement.Target.CompilePush(true) - if referenceCompilationError != nil { - return nil, referenceCompilationError - } - - var caseBlocks []vm.CaseInformation - for _, caseChunk := range switchStatement.CaseBlocks { - targetsAsTuple := &ReturnStatement{ - Results: []IExpression{ - &TupleExpression{ - Values: caseChunk.Cases, - }, - }, - } - targets, targetCompilationError := targetsAsTuple.Compile() - if targetCompilationError != nil { - return nil, targetCompilationError - } - body, bodyCompilationError := compileBody(caseChunk.Body) - if bodyCompilationError != nil { - return nil, bodyCompilationError - } - caseBlocks = append(caseBlocks, - vm.CaseInformation{ - Targets: targets, - Body: body, - }, - ) - } - - var defaultBlock []*vm.Code - if switchStatement.Default != nil { - var defaultBlockCompilationError *errors.Error - defaultBlock, defaultBlockCompilationError = compileBody(switchStatement.Default) - if defaultBlockCompilationError != nil { - return nil, defaultBlockCompilationError - } - } - - var result []*vm.Code - result = append(result, reference...) - result = append(result, - vm.NewCode(vm.SwitchOP, errors.UnknownLine, vm.SwitchInformation{ - Cases: caseBlocks, - Default: defaultBlock, - })) - return result, nil -} - -type ModuleStatement struct { - Statement - Name *Identifier - Body []Node -} - -func (moduleStatement *ModuleStatement) Compile() ([]*vm.Code, *errors.Error) { - body, bodyCompilationError := compileBody(moduleStatement.Body) - if bodyCompilationError != nil { - return nil, bodyCompilationError - } - return []*vm.Code{ - vm.NewCode( - vm.NewModuleOP, - errors.UnknownLine, - vm.ClassInformation{ - Name: moduleStatement.Name.Token.String, - Body: body, - }, - ), - vm.NewCode(vm.PushOP, errors.UnknownLine, nil), - vm.NewCode(vm.AssignIdentifierOP, errors.UnknownLine, moduleStatement.Name.Token.String), - }, nil -} - -type FunctionDefinitionStatement struct { - Statement - Name *Identifier - Arguments []*Identifier - Body []Node -} - -func (functionDefinition *FunctionDefinitionStatement) Compile() ([]*vm.Code, *errors.Error) { - functionCode, functionDefinitionBodyCompilationError := compileBody(functionDefinition.Body) - if functionDefinitionBodyCompilationError != nil { - return nil, functionDefinitionBodyCompilationError - } - var arguments []string - for _, argument := range functionDefinition.Arguments { - arguments = append(arguments, argument.Token.String) - } - - var body []*vm.Code - body = append(body, vm.NewCode(vm.LoadFunctionArgumentsOP, errors.UnknownLine, arguments)) - body = append(body, functionCode...) - body = append(body, vm.NewCode(vm.ReturnOP, errors.UnknownLine, 0)) - - var result []*vm.Code - result = append(result, vm.NewCode(vm.NewFunctionOP, errors.UnknownLine, - vm.FunctionInformation{ - Name: functionDefinition.Name.Token.String, - Body: body, - NumberOfArguments: len(functionDefinition.Arguments), - }, - )) - result = append(result, - vm.NewCode(vm.PushOP, errors.UnknownLine, nil), - ) - result = append( - result, - vm.NewCode( - vm.AssignIdentifierOP, - functionDefinition.Name.Token.Line, - functionDefinition.Name.Token.String, - ), - ) - return result, nil -} - -func (functionDefinition *FunctionDefinitionStatement) CompileAsClassFunction() ([]*vm.Code, *errors.Error, bool) { - functionCode, functionDefinitionBodyCompilationError := compileBody(functionDefinition.Body) - if functionDefinitionBodyCompilationError != nil { - return nil, functionDefinitionBodyCompilationError, false - } - - var arguments []string - for _, argument := range functionDefinition.Arguments { - arguments = append(arguments, argument.Token.String) - } - var body []*vm.Code - body = append(body, vm.NewCode(vm.LoadFunctionArgumentsOP, errors.UnknownLine, arguments)) - body = append(body, functionCode...) - body = append(body, vm.NewCode(vm.ReturnOP, errors.UnknownLine, 0)) - var result []*vm.Code - result = append( - result, - vm.NewCode( - vm.NewClassFunctionOP, - errors.UnknownLine, - vm.FunctionInformation{ - Name: functionDefinition.Name.Token.String, - Body: body, - NumberOfArguments: len(arguments), - }, - ), - ) - - result = append(result, - vm.NewCode(vm.PushOP, errors.UnknownLine, nil), - ) - result = append( - result, - vm.NewCode( - vm.AssignIdentifierOP, - functionDefinition.Name.Token.Line, - functionDefinition.Name.Token.String, - ), - ) - return result, nil, functionDefinition.Name.Token.String == vm.Initialize -} - -type InterfaceStatement struct { - Statement - Name *Identifier - Bases []IExpression - MethodDefinitions []*FunctionDefinitionStatement -} - -func (interfaceStatement *InterfaceStatement) Compile() ([]*vm.Code, *errors.Error) { - var body []*vm.Code - for _, functionDefinition := range interfaceStatement.MethodDefinitions { - function, functionCompilationError := functionDefinition.Compile() - if functionCompilationError != nil { - return nil, functionCompilationError - } - body = append(body, function...) - } - - basesAsTuple := &TupleExpression{ - Values: interfaceStatement.Bases, - } - bases, basesCompilationError := basesAsTuple.CompilePush(true) - if basesCompilationError != nil { - return nil, basesCompilationError - } - var result []*vm.Code - result = append(result, bases...) - result = append(result, vm.NewCode(vm.NewClassOP, errors.UnknownLine, - vm.ClassInformation{ - Name: interfaceStatement.Name.Token.String, - Body: body, - }, - )) - - result = append(result, vm.NewCode(vm.PushOP, errors.UnknownLine, nil)) - result = append(result, vm.NewCode(vm.AssignIdentifierOP, errors.UnknownLine, interfaceStatement.Name.Token.String)) - return result, nil -} - -type ClassStatement struct { - Statement - Name *Identifier - Bases []IExpression // Identifiers and selectors - Body []Node -} - -func (classStatement *ClassStatement) Compile() ([]*vm.Code, *errors.Error) { - basesAsTuple := &TupleExpression{ - Values: classStatement.Bases, - } - bases, basesCompilationError := basesAsTuple.CompilePush(true) - if basesCompilationError != nil { - return nil, basesCompilationError - } - body, bodyCompilationError := compileClassBody(classStatement.Body) - if bodyCompilationError != nil { - return nil, bodyCompilationError - } - var result []*vm.Code - result = append(result, bases...) - result = append(result, vm.NewCode(vm.NewClassOP, errors.UnknownLine, - vm.ClassInformation{ - Name: classStatement.Name.Token.String, - Body: body, - }, - )) - - result = append(result, vm.NewCode(vm.PushOP, errors.UnknownLine, nil)) - result = append(result, vm.NewCode(vm.AssignIdentifierOP, errors.UnknownLine, classStatement.Name.Token.String)) - return result, nil -} - -type ExceptBlock struct { - Targets []IExpression - CaptureName *Identifier - Body []Node -} - -type RaiseStatement struct { - Statement - X IExpression -} - -func (raise *RaiseStatement) Compile() ([]*vm.Code, *errors.Error) { - result, expressionCompilationError := raise.X.CompilePush(true) - if expressionCompilationError != nil { - return nil, expressionCompilationError - } - result = append(result, vm.NewCode(vm.RaiseOP, errors.UnknownLine, nil)) - return result, nil -} - -type TryStatement struct { - Statement - Body []Node - ExceptBlocks []*ExceptBlock - Else []Node - Finally []Node -} - -func (tryStatement *TryStatement) Compile() ([]*vm.Code, *errors.Error) { - body, bodyCompilationError := compileBody(tryStatement.Body) - if bodyCompilationError != nil { - return nil, bodyCompilationError - } - var exceptInformation []vm.ExceptInformation - for _, except := range tryStatement.ExceptBlocks { - captureName := "" - if except.CaptureName != nil { - captureName = except.CaptureName.Token.String - } - targetsReturn := &ReturnStatement{ - Results: []IExpression{ - &TupleExpression{ - Values: except.Targets, - }, - }, - } - targets, targetsCompilationError := targetsReturn.Compile() - if targetsCompilationError != nil { - return nil, targetsCompilationError - } - exceptBody, exceptCompilationError := compileBody(except.Body) - if exceptCompilationError != nil { - return nil, exceptCompilationError - } - - exceptBlock := vm.ExceptInformation{ - CaptureName: captureName, - Targets: targets, - Body: exceptBody, - } - exceptInformation = append(exceptInformation, exceptBlock) - } - if tryStatement.Else != nil { - elseBody, elseCompilationError := compileBody(tryStatement.Else) - if elseCompilationError != nil { - return nil, elseCompilationError - } - exceptInformation = append(exceptInformation, - vm.ExceptInformation{ - CaptureName: "", - Targets: nil, - Body: elseBody, - }, - ) - } - var finally []*vm.Code - if tryStatement.Finally != nil { - var finallyCompilationError *errors.Error - finally, finallyCompilationError = compileBody(tryStatement.Finally) - if finallyCompilationError != nil { - return nil, finallyCompilationError - } - } - var result []*vm.Code - result = append(result, - vm.NewCode(vm.TryOP, errors.UnknownLine, vm.TryInformation{ - Body: body, - Excepts: exceptInformation, - Finally: finally, - })) - return result, nil -} - -type BeginStatement struct { - Statement - Body []Node -} - -func (beginStatement *BeginStatement) Compile() ([]*vm.Code, *errors.Error) { - return compileBody(beginStatement.Body) -} - -type EndStatement struct { - Statement - Body []Node -} - -func (endStatement *EndStatement) Compile() ([]*vm.Code, *errors.Error) { - return compileBody(endStatement.Body) -} - -type ReturnStatement struct { - Statement - Results []IExpression -} - -func (returnStatement *ReturnStatement) Compile() ([]*vm.Code, *errors.Error) { - numberOfResults := len(returnStatement.Results) - var result []*vm.Code - for i := numberOfResults - 1; i > -1; i-- { - returnResult, resultCompilationError := returnStatement.Results[i].CompilePush(true) - if resultCompilationError != nil { - return nil, resultCompilationError - } - result = append(result, returnResult...) - } - return append(result, vm.NewCode(vm.ReturnOP, errors.UnknownLine, numberOfResults)), nil -} - -type YieldStatement struct { - Statement - Results []IExpression -} - -type ContinueStatement struct { - Statement -} - -func (_ *ContinueStatement) Compile() ([]*vm.Code, *errors.Error) { - return []*vm.Code{vm.NewCode(vm.ContinueOP, errors.UnknownLine, nil)}, nil -} - -type BreakStatement struct { - Statement -} - -func (_ *BreakStatement) Compile() ([]*vm.Code, *errors.Error) { - return []*vm.Code{vm.NewCode(vm.BreakOP, errors.UnknownLine, nil)}, nil -} - -type RedoStatement struct { - Statement -} - -func (_ *RedoStatement) Compile() ([]*vm.Code, *errors.Error) { - return []*vm.Code{vm.NewCode(vm.RedoOP, errors.UnknownLine, nil)}, nil -} - -type PassStatement struct { - Statement -} - -func (_ *PassStatement) Compile() ([]*vm.Code, *errors.Error) { - return []*vm.Code{vm.NewCode(vm.NOP, errors.UnknownLine, nil)}, nil -} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/compiler/compile.go b/vendor/github.com/shoriwe/gplasma/pkg/compiler/compile.go new file mode 100644 index 0000000..8a08fbd --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/compiler/compile.go @@ -0,0 +1,42 @@ +package compiler + +import ( + "fmt" + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/bytecode/assembler" + "github.com/shoriwe/gplasma/pkg/lexer" + "github.com/shoriwe/gplasma/pkg/parser" + "github.com/shoriwe/gplasma/pkg/passes/checks" + "github.com/shoriwe/gplasma/pkg/passes/simplification" + transformations_1 "github.com/shoriwe/gplasma/pkg/passes/transformations-1" + "github.com/shoriwe/gplasma/pkg/reader" +) + +func Compile(scriptCode string) ([]byte, error) { + l := lexer.NewLexer(reader.NewStringReader(scriptCode)) + p := parser.NewParser(l) + programAst1, parseError := p.Parse() + if parseError != nil { + return nil, parseError + } + checkPass := checks.NewCheckPass() + ast.Walk(checkPass, programAst1) + if checkPass.CountInvalidLoopNodes() > 0 { + return nil, fmt.Errorf("invalid loop nodes found") + } + if checkPass.CountInvalidFunctionNodes() > 0 { + return nil, fmt.Errorf("invalid function nodes found") + } + if checkPass.CountInvalidGeneratorNodes() > 0 { + return nil, fmt.Errorf("invalid generator nodes found") + } + programAst2, simplifyError := simplification.Simplify(programAst1) + if simplifyError != nil { + return nil, simplifyError + } + programAst3, transformError := transformations_1.Transform(programAst2) + if transformError != nil { + return nil, transformError + } + return assembler.Assemble(programAst3) +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/compiler/lexer/lexer.go b/vendor/github.com/shoriwe/gplasma/pkg/compiler/lexer/lexer.go deleted file mode 100644 index 70cd32d..0000000 --- a/vendor/github.com/shoriwe/gplasma/pkg/compiler/lexer/lexer.go +++ /dev/null @@ -1,629 +0,0 @@ -package lexer - -import ( - "github.com/shoriwe/gplasma/pkg/errors" - "github.com/shoriwe/gplasma/pkg/reader" - "regexp" -) - -var ( - identifierCheck = regexp.MustCompile("(?m)^[a-zA-Z_]+[a-zA-Z0-9_]*$") - junkKindCheck = regexp.MustCompile("(?m)^\\00+$") -) - -type Lexer struct { - lastToken *Token - line int - reader reader.Reader - complete bool -} - -func (lexer *Lexer) HasNext() bool { - return !lexer.complete -} - -func (lexer *Lexer) tokenizeStringLikeExpressions(stringOpener rune) ([]rune, uint8, uint8, *errors.Error) { - content := []rune{stringOpener} - var target uint8 - switch stringOpener { - case '\'': - target = SingleQuoteString - case '"': - target = DoubleQuoteString - case '`': - target = CommandOutput - } - var directValue = Unknown - var tokenizingError *errors.Error - escaped := false - finish := false - for ; lexer.reader.HasNext() && !finish; lexer.reader.Next() { - char := lexer.reader.Char() - if escaped { - switch char { - case '\\', '\'', '"', '`', 'a', 'b', 'e', 'f', 'n', 'r', 't', '?', 'u', 'x': - escaped = false - default: - tokenizingError = errors.New(lexer.line, "invalid escape sequence", errors.LexingError) - finish = true - } - } else { - switch char { - case '\n': - lexer.line++ - case stringOpener: - directValue = target - finish = true - case '\\': - escaped = true - } - } - content = append(content, char) - } - if directValue != target { - tokenizingError = errors.New(lexer.line, "string never closed", errors.LexingError) - } - return content, Literal, directValue, tokenizingError -} - -func (lexer *Lexer) tokenizeHexadecimal(letterX rune) ([]rune, uint8, uint8, *errors.Error) { - result := []rune{'0', letterX} - if !lexer.reader.HasNext() { - return result, Literal, Unknown, errors.NewUnknownTokenKindError(lexer.line) - } - nextDigit := lexer.reader.Char() - if !(('0' <= nextDigit && nextDigit <= '9') || - ('a' <= nextDigit && nextDigit <= 'f') || - ('A' <= nextDigit && nextDigit <= 'F')) { - return result, Literal, Unknown, errors.NewUnknownTokenKindError(lexer.line) - } - lexer.reader.Next() - result = append(result, nextDigit) - for ; lexer.reader.HasNext(); lexer.reader.Next() { - nextDigit = lexer.reader.Char() - if !(('0' <= nextDigit && nextDigit <= '9') || ('a' <= nextDigit && nextDigit <= 'f') || ('A' <= nextDigit && nextDigit <= 'F')) && nextDigit != '_' { - return result, Literal, HexadecimalInteger, nil - } - result = append(result, nextDigit) - } - return result, Literal, HexadecimalInteger, nil -} - -func (lexer *Lexer) tokenizeBinary(letterB rune) ([]rune, uint8, uint8, *errors.Error) { - result := []rune{'0', letterB} - if !lexer.reader.HasNext() { - return result, Literal, Unknown, errors.NewUnknownTokenKindError(lexer.line) - } - nextDigit := lexer.reader.Char() - if !(nextDigit == '0' || nextDigit == '1') { - return result, Literal, Unknown, errors.NewUnknownTokenKindError(lexer.line) - } - lexer.reader.Next() - result = append(result, nextDigit) - for ; lexer.reader.HasNext(); lexer.reader.Next() { - nextDigit = lexer.reader.Char() - if !(nextDigit == '0' || nextDigit == '1') && nextDigit != '_' { - return result, Literal, BinaryInteger, nil - } - result = append(result, nextDigit) - } - return result, Literal, BinaryInteger, nil -} - -func (lexer *Lexer) tokenizeOctal(letterO rune) ([]rune, uint8, uint8, *errors.Error) { - result := []rune{'0', letterO} - if !lexer.reader.HasNext() { - return result, Literal, Unknown, errors.NewUnknownTokenKindError(lexer.line) - } - nextDigit := lexer.reader.Char() - if !('0' <= nextDigit && nextDigit <= '7') { - return result, Literal, Unknown, errors.NewUnknownTokenKindError(lexer.line) - } - lexer.reader.Next() - result = append(result, nextDigit) - for ; lexer.reader.HasNext(); lexer.reader.Next() { - nextDigit = lexer.reader.Char() - if !('0' <= nextDigit && nextDigit <= '7') && nextDigit != '_' { - return result, Literal, OctalInteger, nil - } - result = append(result, nextDigit) - } - return result, Literal, OctalInteger, nil -} - -func (lexer *Lexer) tokenizeScientificFloat(base []rune) ([]rune, uint8, uint8, *errors.Error) { - result := base - if !lexer.reader.HasNext() { - return result, Literal, Unknown, errors.NewUnknownTokenKindError(lexer.line) - } - direction := lexer.reader.Char() - if (direction != '-') && (direction != '+') { - return result, Literal, Unknown, errors.NewUnknownTokenKindError(lexer.line) - } - lexer.reader.Next() - // Ensure next is a number - if !lexer.reader.HasNext() { - return result, Literal, Unknown, errors.NewUnknownTokenKindError(lexer.line) - } - result = append(result, direction) - nextDigit := lexer.reader.Char() - if !('0' <= nextDigit && nextDigit <= '9') { - return result, Literal, Unknown, errors.NewUnknownTokenKindError(lexer.line) - } - result = append(result, nextDigit) - lexer.reader.Next() - for ; lexer.reader.HasNext(); lexer.reader.Next() { - nextDigit = lexer.reader.Char() - if !('0' <= nextDigit && nextDigit <= '9') && nextDigit != '_' { - return result, Literal, ScientificFloat, nil - } - result = append(result, nextDigit) - } - return result, Literal, ScientificFloat, nil -} - -func (lexer *Lexer) tokenizeFloat(base []rune) ([]rune, uint8, uint8, *errors.Error) { - if !lexer.reader.HasNext() { - lexer.reader.Redo() - return base[:len(base)-1], Literal, Integer, nil - } - nextDigit := lexer.reader.Char() - if !('0' <= nextDigit && nextDigit <= '9') { - lexer.reader.Redo() - return base[:len(base)-1], Literal, Integer, nil - } - lexer.reader.Next() - result := append(base, nextDigit) - for ; lexer.reader.HasNext(); lexer.reader.Next() { - nextDigit = lexer.reader.Char() - if ('0' <= nextDigit && nextDigit <= '9') || nextDigit == '_' { - result = append(result, nextDigit) - } else if (nextDigit == 'e') || (nextDigit == 'E') { - lexer.reader.Next() - return lexer.tokenizeScientificFloat(append(result, nextDigit)) - } else { - break - } - } - return result, Literal, Float, nil -} - -func (lexer *Lexer) tokenizeInteger(base []rune) ([]rune, uint8, uint8, *errors.Error) { - if !lexer.reader.HasNext() { - return base, Literal, Integer, nil - } - nextDigit := lexer.reader.Char() - if nextDigit == '.' { - lexer.reader.Next() - return lexer.tokenizeFloat(append(base, nextDigit)) - } else if nextDigit == 'e' || nextDigit == 'E' { - lexer.reader.Next() - return lexer.tokenizeScientificFloat(append(base, nextDigit)) - } else if !('0' <= nextDigit && nextDigit <= '9') { - return base, Literal, Integer, nil - } - lexer.reader.Next() - result := append(base, nextDigit) - for ; lexer.reader.HasNext(); lexer.reader.Next() { - nextDigit = lexer.reader.Char() - if nextDigit == 'e' || nextDigit == 'E' { - return lexer.tokenizeScientificFloat(append(result, nextDigit)) - } else if nextDigit == '.' { - lexer.reader.Next() - return lexer.tokenizeFloat(append(result, nextDigit)) - } else if ('0' <= nextDigit && nextDigit <= '9') || nextDigit == '_' { - result = append(result, nextDigit) - } else { - break - } - } - return result, Literal, Integer, nil -} - -func (lexer *Lexer) tokenizeNumeric(firstDigit rune) ([]rune, uint8, uint8, *errors.Error) { - if !lexer.reader.HasNext() { - return []rune{firstDigit}, Literal, Integer, nil - } - nextChar := lexer.reader.Char() - lexer.reader.Next() - if firstDigit == '0' { - switch nextChar { - case 'x', 'X': // Hexadecimal - return lexer.tokenizeHexadecimal(nextChar) - case 'b', 'B': // Binary - return lexer.tokenizeBinary(nextChar) - case 'o', 'O': // Octal - return lexer.tokenizeOctal(nextChar) - case 'e', 'E': // Scientific float - return lexer.tokenizeScientificFloat([]rune{firstDigit, nextChar}) - case '.': // Maybe a float - return lexer.tokenizeFloat([]rune{firstDigit, nextChar}) // Integer, Float Or Scientific Float - default: - if ('0' <= nextChar && nextChar <= '9') || nextChar == '_' { - return lexer.tokenizeInteger([]rune{firstDigit, nextChar}) // Integer, Float or Scientific Float - } - } - } else { - switch nextChar { - case 'e', 'E': // Scientific float - return lexer.tokenizeScientificFloat([]rune{firstDigit, nextChar}) - case '.': // Maybe a float - return lexer.tokenizeFloat([]rune{firstDigit, nextChar}) // Integer, Float Or Scientific Float - default: - if ('0' <= nextChar && nextChar <= '9') || nextChar == '_' { - return lexer.tokenizeInteger([]rune{firstDigit, nextChar}) // Integer, Float or Scientific Float - } - } - } - lexer.reader.Redo() - return []rune{firstDigit}, Literal, Integer, nil -} - -func guessKind(buffer []rune) (uint8, uint8) { - - switch string(buffer) { - case PassString: - return Keyboard, Pass - case EndString: - return Keyboard, End - case IfString: - return Keyboard, If - case UnlessString: - return Keyboard, Unless - case ElseString: - return Keyboard, Else - case ElifString: - return Keyboard, Elif - case WhileString: - return Keyboard, While - case DoString: - return Keyboard, Do - case ForString: - return Keyboard, For - case UntilString: - return Keyboard, Until - case SwitchString: - return Keyboard, Switch - case CaseString: - return Keyboard, Case - case DefaultString: - return Keyboard, Default - case YieldString: - return Keyboard, Yield - case ReturnString: - return Keyboard, Return - case ContinueString: - return Keyboard, Continue - case BreakString: - return Keyboard, Break - case RedoString: - return Keyboard, Redo - case ModuleString: - return Keyboard, Module - case DefString: - return Keyboard, Def - case LambdaString: - return Keyboard, Lambda - case InterfaceString: - return Keyboard, Interface - case ClassString: - return Keyboard, Class - case TryString: - return Keyboard, Try - case ExceptString: - return Keyboard, Except - case FinallyString: - return Keyboard, Finally - case AndString: - return Comparator, And - case OrString: - return Comparator, Or - case XorString: - return Comparator, Xor - case InString: - return Comparator, In - case AsString: - return Keyboard, As - case RaiseString: - return Keyboard, Raise - case BEGINString: - return Keyboard, BEGIN - case ENDString: - return Keyboard, END - case NotString: // Unary operator - return Operator, Not - case TrueString: - return Boolean, True - case FalseString: - return Boolean, False - case NoneString: - return NoneType, None - case ContextString: - return Keyboard, Context - default: - if identifierCheck.MatchString(string(buffer)) { - return IdentifierKind, Unknown - } else if junkKindCheck.MatchString(string(buffer)) { - return JunkKind, Unknown - } - } - return Unknown, Unknown -} - -func (lexer *Lexer) tokenizeChars(startingChar rune) ([]rune, uint8, uint8, *errors.Error) { - content := []rune{startingChar} - for ; lexer.reader.HasNext(); lexer.reader.Next() { - char := lexer.reader.Char() - if ('a' <= char && char <= 'z') || ('A' <= char && char <= 'Z') || ('0' <= char && char <= '9') || (char == '_') { - content = append(content, char) - } else { - break - } - } - kind, directValue := guessKind(content) - return content, kind, directValue, nil -} - -func (lexer *Lexer) tokenizeComment() ([]rune, uint8, *errors.Error) { - var content []rune - for ; lexer.reader.HasNext(); lexer.reader.Next() { - char := lexer.reader.Char() - if char == '\n' { - break - } - content = append(content, char) - } - return content, Comment, nil -} - -func (lexer *Lexer) tokenizeRepeatableOperator(char rune, singleDirectValue uint8, singleKind uint8, doubleDirectValue uint8, doubleKind uint8, assignSingleDirectValue uint8, assignDoubleDirectValue uint8, assignSingleKind uint8, assignDoubleKind uint8) ([]rune, uint8, uint8) { - content := []rune{char} - kind := singleKind - directValue := singleDirectValue - if lexer.reader.HasNext() { - nextChar := lexer.reader.Char() - if nextChar == char { - content = append(content, nextChar) - lexer.reader.Next() - kind = doubleKind - directValue = doubleDirectValue - if lexer.reader.HasNext() { - nextNextChar := lexer.reader.Char() - if nextNextChar == '=' { - content = append(content, nextNextChar) - kind = assignDoubleKind - lexer.reader.Next() - directValue = assignDoubleDirectValue - } - } - } else if nextChar == '=' { - kind = assignSingleKind - content = append(content, nextChar) - lexer.reader.Next() - directValue = assignSingleDirectValue - } - } - return content, kind, directValue -} - -func (lexer *Lexer) tokenizeNotRepeatableOperator(char rune, single uint8, singleKind uint8, assign uint8, assignKind uint8) ([]rune, uint8, uint8) { - content := []rune{char} - kind := singleKind - directValue := single - if lexer.reader.HasNext() { - nextChar := lexer.reader.Char() - if nextChar == '=' { - kind = assignKind - directValue = assign - content = append(content, nextChar) - lexer.reader.Next() - } - } - return content, kind, directValue -} -func (lexer *Lexer) next() (*Token, *errors.Error) { - if !lexer.reader.HasNext() { - lexer.complete = true - return &Token{ - String: "EOF", - DirectValue: EOF, - Kind: EOF, - Line: lexer.line, - Index: lexer.reader.Index(), - }, nil - } - var tokenizingError *errors.Error - var kind uint8 - var content []rune - directValue := Unknown - line := lexer.line - index := lexer.reader.Index() - char := lexer.reader.Char() - lexer.reader.Next() - switch char { - case '\r': - if lexer.reader.Char() == NewLineChar { - lexer.reader.Next() - lexer.line++ - content = []rune{char} - kind = Separator - directValue = NewLine - } - case NewLineChar: - lexer.line++ - content = []rune{char} - kind = Separator - directValue = NewLine - case SemiColonChar: - content = []rune{char} - kind = Separator - directValue = SemiColon - case ColonChar: - content = []rune{char} - directValue = Colon - kind = Punctuation - case CommaChar: - content = []rune{char} - directValue = Comma - kind = Punctuation - case OpenParenthesesChar: - content = []rune{char} - directValue = OpenParentheses - kind = Punctuation - case CloseParenthesesChar: - content = []rune{char} - directValue = CloseParentheses - kind = Punctuation - case OpenSquareBracketChar: - content = []rune{char} - directValue = OpenSquareBracket - kind = Punctuation - case CloseSquareBracketChar: - content = []rune{char} - directValue = CloseSquareBracket - kind = Punctuation - case OpenBraceChar: - content = []rune{char} - directValue = OpenBrace - kind = Punctuation - case CloseBraceChar: - content = []rune{char} - directValue = CloseBrace - kind = Punctuation - case DollarSignChar: - content = []rune{char} - directValue = DollarSign - kind = Punctuation - case DotChar: - content = []rune{char} - directValue = Dot - kind = Punctuation - case WhiteSpaceChar: - directValue = Whitespace - kind = Whitespace - content = []rune{char} - case TabChar: - directValue = Tab - kind = Whitespace - content = []rune{char} - case CommentChar: - content, kind, tokenizingError = lexer.tokenizeComment() - content = append([]rune{'#'}, content...) - case '\'', '"': // String1 - content, kind, directValue, tokenizingError = lexer.tokenizeStringLikeExpressions(char) - case '`': - content, kind, directValue, tokenizingError = lexer.tokenizeStringLikeExpressions(char) - case '1', '2', '3', '4', '5', '6', '7', '8', '9', '0': - content, kind, directValue, tokenizingError = lexer.tokenizeNumeric(char) - case StarChar: - content, kind, directValue = lexer.tokenizeRepeatableOperator(char, Star, Operator, PowerOf, Operator, StarAssign, PowerOfAssign, Assignment, Assignment) - case DivChar: - content, kind, directValue = lexer.tokenizeRepeatableOperator(char, Div, Operator, FloorDiv, Operator, DivAssign, FloorDivAssign, Assignment, Assignment) - case LessThanChar: - content, kind, directValue = lexer.tokenizeRepeatableOperator(char, LessThan, Comparator, BitwiseLeft, Operator, LessOrEqualThan, BitwiseLeftAssign, Comparator, Assignment) - case GreatThanChar: - content, kind, directValue = lexer.tokenizeRepeatableOperator(char, GreaterThan, Comparator, BitwiseRight, Operator, GreaterOrEqualThan, BitwiseRightAssign, Comparator, Assignment) - case AddChar: - content, kind, directValue = lexer.tokenizeNotRepeatableOperator(char, Add, Operator, AddAssign, Assignment) - case SubChar: - content, kind, directValue = lexer.tokenizeNotRepeatableOperator(char, Sub, Operator, SubAssign, Assignment) - case ModulusChar: - content, kind, directValue = lexer.tokenizeNotRepeatableOperator(char, Modulus, Operator, ModulusAssign, Assignment) - case BitwiseXorChar: - content, kind, directValue = lexer.tokenizeNotRepeatableOperator(char, BitwiseXor, Operator, BitwiseXorAssign, Assignment) - case BitWiseAndChar: - content, kind, directValue = lexer.tokenizeNotRepeatableOperator(char, BitWiseAnd, Operator, BitWiseAndAssign, Assignment) - case BitwiseOrChar: - content, kind, directValue = lexer.tokenizeNotRepeatableOperator(char, BitwiseOr, Operator, BitwiseOrAssign, Assignment) - case SignNotChar: - content, kind, directValue = lexer.tokenizeNotRepeatableOperator(char, SignNot, Operator, NotEqual, Comparator) - case NegateBitsChar: - content, kind, directValue = lexer.tokenizeNotRepeatableOperator(char, NegateBits, Operator, NegateBitsAssign, Assignment) - case EqualsChar: - content, kind, directValue = lexer.tokenizeNotRepeatableOperator(char, Assign, Assignment, Equals, Comparator) - case BackSlashChar: - content = []rune{char} - if lexer.reader.HasNext() { - nextChar := lexer.reader.Char() - if nextChar != '\n' { - return nil, errors.New(lexer.line, "line escape not followed by a new line", errors.LexingError) - } - content = append(content, '\n') - lexer.reader.Next() - } - kind = PendingEscape - default: - if char == 'b' { - if lexer.reader.HasNext() { - nextChar := lexer.reader.Char() - if nextChar == '\'' || nextChar == '"' { - var byteStringPart []rune - lexer.reader.Next() - byteStringPart, kind, directValue, tokenizingError = lexer.tokenizeStringLikeExpressions(nextChar) - content = append([]rune{char}, byteStringPart...) - if directValue != Unknown { - directValue = ByteString - } - break - } - } - } - content, kind, directValue, tokenizingError = lexer.tokenizeChars(char) - } - return &Token{ - DirectValue: directValue, - String: string(content), - Kind: kind, - Line: line, - Index: index, - }, tokenizingError -} - -/* - This function will yield just the necessary token, this means not repeated separators -*/ -func (lexer *Lexer) Next() (*Token, *errors.Error) { - token, tokenizingError := lexer.next() - if tokenizingError != nil { - return nil, tokenizingError - } - if token.Kind == JunkKind { - return lexer.Next() - } - if token.Kind == Comment { - return lexer.Next() - } - if token.Kind == Whitespace { - return lexer.Next() - } - if token.Kind == Separator { - if lexer.lastToken == nil { - return lexer.Next() - } - switch lexer.lastToken.Kind { - case Separator: - return lexer.Next() - case Operator, Comparator: - return lexer.Next() - default: - break - } - switch lexer.lastToken.DirectValue { - case Comma, OpenParentheses, OpenSquareBracket, OpenBrace: - return lexer.Next() - default: - break - } - } - lexer.lastToken = token - return token, nil -} - -func NewLexer(codeReader reader.Reader) *Lexer { - return &Lexer{ - lastToken: nil, - line: 1, - reader: codeReader, - complete: false, - } -} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/compiler/parser/parser.go b/vendor/github.com/shoriwe/gplasma/pkg/compiler/parser/parser.go deleted file mode 100644 index 4bcde2a..0000000 --- a/vendor/github.com/shoriwe/gplasma/pkg/compiler/parser/parser.go +++ /dev/null @@ -1,2477 +0,0 @@ -package parser - -import ( - "fmt" - "github.com/shoriwe/gplasma/pkg/compiler/ast" - "github.com/shoriwe/gplasma/pkg/compiler/lexer" - "github.com/shoriwe/gplasma/pkg/errors" -) - -const ( - ForStatement = "For Statement" - UntilStatement = "Until Statement" - ModuleStatement = "Module Statement" - FunctionDefinitionStatement = "Function Definition Statement" - ClassStatement = "Class Statement" - RaiseStatement = "Raise Statement" - TryStatement = "Try Statement" - ExceptBlock = "Except Block" - ElseBlock = "Else Block" - FinallyBlock = "Finally Block" - BeginStatement = "Begin Statement" - EndStatement = "End Statement" - InterfaceStatement = "Interface Statement" - BinaryExpression = "Binary Expression" - PointerExpression = "Pointer Expression" - LambdaExpression = "Lambda Expression" - ParenthesesExpression = "Parentheses Expression" - TupleExpression = "Tuple Expression" - ArrayExpression = "Array Expression" - HashExpression = "Hash Expression" - WhileStatement = "While Statement" - DoWhileStatement = "Do-While Statement" - IfStatement = "If Statement" - ElifBlock = "Elif Block" - UnlessStatement = "Unless Statement" - SwitchStatement = "Switch Statement" - CaseBlock = "Targets Block" - DefaultBlock = "Default Block" - ReturnStatement = "Return Statement" - YieldStatement = "Yield Statement" - SuperStatement = "Super Statement" - SelectorExpression = "Selector Expression" - MethodInvocationExpression = "Method Invocation Expression" - IndexExpression = "Index Expression" - IfOneLinerExpression = "If One Liner Expression" - UnlessOneLinerExpression = "Unless One Liner Expression" - OneLineElseBlock = "One Line Else Block" - GeneratorExpression = "Generator Expression" - AssignStatement = "Assign Statement" -) - -func newSyntaxError(line int, nodeType string) *errors.Error { - return errors.New(line, fmt.Sprintf("invalid definition of %s", nodeType), errors.SyntaxError) -} - -func newNonExpressionReceivedError(line int, nodeType string) *errors.Error { - return errors.New(line, fmt.Sprintf("received a non expression in %s", nodeType), errors.SyntaxError) -} - -func newNonIdentifierReceivedError(line int, nodeType string) *errors.Error { - return errors.New(line, fmt.Sprintf("received a non identifier in %s", nodeType), errors.SyntaxError) -} - -func newStatementNeverEndedError(line int, nodeType string) *errors.Error { - return errors.New(line, fmt.Sprintf("%s never ended", nodeType), errors.SyntaxError) -} - -func newInvalidKindOfTokenError(line int) *errors.Error { - return errors.New(line, "invalid kind of token", errors.ParsingError) -} - -func newExpressionNeverClosedError(line int, nodeType string) *errors.Error { - return errors.New(line, fmt.Sprintf("%s never closed", nodeType), errors.SyntaxError) -} - -func newNonFunctionDefinitionReceived(line int, nodeType string) *errors.Error { - return errors.New(line, fmt.Sprintf("non function definition received in %s", nodeType), errors.SyntaxError) -} - -type Parser struct { - lexer *lexer.Lexer - complete bool - currentToken *lexer.Token -} - -func (parser *Parser) hasNext() bool { - return !parser.complete -} - -func (parser *Parser) next() *errors.Error { - token, tokenizingError := parser.lexer.Next() - if tokenizingError != nil { - return tokenizingError - } - if token.Kind == lexer.EOF { - parser.complete = true - } - parser.currentToken = token - return nil -} - -func (parser *Parser) directValueMatch(directValue uint8) bool { - if parser.currentToken == nil { - return false - } - return parser.currentToken.DirectValue == directValue -} - -func (parser *Parser) kindMatch(kind uint8) bool { - if parser.currentToken == nil { - return false - } - return parser.currentToken.Kind == kind -} - -func (parser *Parser) currentLine() int { - if parser.currentToken == nil { - return 0 - } - return parser.currentToken.Line -} - -func (parser *Parser) matchString(value string) bool { - if parser.currentToken == nil { - return false - } - return parser.currentToken.String == value -} - -func (parser *Parser) parseForStatement() (*ast.ForLoopStatement, *errors.Error) { - tokenizingError := parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - newLinesRemoveError := parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - var receivers []*ast.Identifier - for parser.hasNext() { - if parser.directValueMatch(lexer.In) { - break - } else if !parser.kindMatch(lexer.IdentifierKind) { - return nil, newSyntaxError(parser.currentLine(), ForStatement) - } - newLinesRemoveError = parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - receivers = append(receivers, &ast.Identifier{ - Token: parser.currentToken, - }) - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - newLinesRemoveError = parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - if parser.directValueMatch(lexer.Comma) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - } else if parser.directValueMatch(lexer.In) { - break - } else { - return nil, newSyntaxError(parser.currentLine(), ForStatement) - } - } - newLinesRemoveError = parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - if !parser.directValueMatch(lexer.In) { - return nil, newSyntaxError(parser.currentLine(), ForStatement) - } - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - newLinesRemoveError = parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - source, parsingError := parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - if _, ok := source.(ast.IExpression); !ok { - return nil, newNonExpressionReceivedError(parser.currentLine(), ForStatement) - } - if !parser.directValueMatch(lexer.NewLine) { - return nil, newSyntaxError(parser.currentLine(), ForStatement) - } - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - var body []ast.Node - var bodyNode ast.Node - for parser.hasNext() { - if parser.kindMatch(lexer.Separator) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - if parser.directValueMatch(lexer.End) { - break - } - continue - } - bodyNode, parsingError = parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - body = append(body, bodyNode) - } - if !parser.directValueMatch(lexer.End) { - return nil, newStatementNeverEndedError(parser.currentLine(), ForStatement) - } - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - return &ast.ForLoopStatement{ - Receivers: receivers, - Source: source.(ast.IExpression), - Body: body, - }, nil -} - -func (parser *Parser) parseUntilStatement() (*ast.UntilLoopStatement, *errors.Error) { - tokenizingError := parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - newLinesRemoveError := parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - condition, parsingError := parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - if _, ok := condition.(ast.IExpression); !ok { - return nil, newSyntaxError(parser.currentLine(), UntilStatement) - } - if !parser.directValueMatch(lexer.NewLine) { - return nil, newSyntaxError(parser.currentLine(), UntilStatement) - } - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - var bodyNode ast.Node - var body []ast.Node - for parser.hasNext() { - if parser.kindMatch(lexer.Separator) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - if parser.directValueMatch(lexer.End) { - break - } - continue - } - bodyNode, parsingError = parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - body = append(body, bodyNode) - } - if !parser.directValueMatch(lexer.End) { - return nil, newStatementNeverEndedError(parser.currentLine(), UntilStatement) - } - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - return &ast.UntilLoopStatement{ - Condition: condition.(ast.IExpression), - Body: body, - }, nil -} - -func (parser *Parser) parseModuleStatement() (*ast.ModuleStatement, *errors.Error) { - tokenizingError := parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - newLinesRemoveError := parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - if !parser.kindMatch(lexer.IdentifierKind) { - return nil, newSyntaxError(parser.currentLine(), ModuleStatement) - } - name := &ast.Identifier{ - Token: parser.currentToken, - } - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - if !parser.directValueMatch(lexer.NewLine) { - return nil, newSyntaxError(parser.currentLine(), ModuleStatement) - } - var body []ast.Node - var bodyNode ast.Node - var parsingError *errors.Error - for parser.hasNext() { - if parser.kindMatch(lexer.Separator) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - if parser.directValueMatch(lexer.End) { - break - } - continue - } - bodyNode, parsingError = parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - body = append(body, bodyNode) - } - if !parser.directValueMatch(lexer.End) { - return nil, newStatementNeverEndedError(parser.currentLine(), ModuleStatement) - } - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - return &ast.ModuleStatement{ - Name: name, - Body: body, - }, nil -} - -func (parser *Parser) parseFunctionDefinitionStatement() (*ast.FunctionDefinitionStatement, *errors.Error) { - tokenizingError := parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - newLinesRemoveError := parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - if !parser.kindMatch(lexer.IdentifierKind) { - return nil, newSyntaxError(parser.currentLine(), FunctionDefinitionStatement) - } - name := &ast.Identifier{ - Token: parser.currentToken, - } - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - newLinesRemoveError = parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - if !parser.directValueMatch(lexer.OpenParentheses) { - return nil, newSyntaxError(parser.currentLine(), FunctionDefinitionStatement) - } - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - var arguments []*ast.Identifier - for parser.hasNext() { - if parser.directValueMatch(lexer.CloseParentheses) { - break - } - newLinesRemoveError = parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - if !parser.kindMatch(lexer.IdentifierKind) { - return nil, newSyntaxError(parser.currentLine(), FunctionDefinitionStatement) - } - argument := &ast.Identifier{ - Token: parser.currentToken, - } - arguments = append(arguments, argument) - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - newLinesRemoveError = parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - if parser.directValueMatch(lexer.Comma) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - } else if parser.directValueMatch(lexer.CloseParentheses) { - break - } else { - return nil, newSyntaxError(parser.currentLine(), FunctionDefinitionStatement) - } - } - if !parser.directValueMatch(lexer.CloseParentheses) { - return nil, newSyntaxError(parser.currentLine(), FunctionDefinitionStatement) - } - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - if !parser.directValueMatch(lexer.NewLine) { - return nil, newSyntaxError(parser.currentLine(), FunctionDefinitionStatement) - } - var body []ast.Node - var bodyNode ast.Node - var parsingError *errors.Error - for parser.hasNext() { - if parser.kindMatch(lexer.Separator) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - if parser.directValueMatch(lexer.End) { - break - } - continue - } - bodyNode, parsingError = parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - body = append(body, bodyNode) - } - if !parser.directValueMatch(lexer.End) { - return nil, newStatementNeverEndedError(parser.currentLine(), FunctionDefinitionStatement) - } - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - return &ast.FunctionDefinitionStatement{ - Name: name, - Arguments: arguments, - Body: body, - }, nil -} - -func (parser *Parser) parseClassStatement() (*ast.ClassStatement, *errors.Error) { - tokenizingError := parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - newLinesRemoveError := parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - if !parser.kindMatch(lexer.IdentifierKind) { - return nil, newSyntaxError(parser.currentLine(), ClassStatement) - } - name := &ast.Identifier{ - Token: parser.currentToken, - } - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - var bases []ast.IExpression - var base ast.Node - var parsingError *errors.Error - if parser.directValueMatch(lexer.OpenParentheses) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - for parser.hasNext() { - newLinesRemoveError = parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - base, parsingError = parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - if _, ok := base.(ast.IExpression); !ok { - return nil, newNonExpressionReceivedError(parser.currentLine(), ClassStatement) - } - bases = append(bases, base.(ast.IExpression)) - newLinesRemoveError = parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - if parser.directValueMatch(lexer.Comma) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - } else if parser.directValueMatch(lexer.CloseParentheses) { - break - } else { - return nil, newSyntaxError(parser.currentLine(), ClassStatement) - } - } - if !parser.directValueMatch(lexer.CloseParentheses) { - return nil, newSyntaxError(parser.currentLine(), ClassStatement) - } - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - } - if !parser.directValueMatch(lexer.NewLine) { - return nil, newSyntaxError(parser.currentLine(), ClassStatement) - } - var body []ast.Node - var bodyNode ast.Node - for parser.hasNext() { - if parser.kindMatch(lexer.Separator) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - if parser.directValueMatch(lexer.End) { - break - } - continue - } - bodyNode, parsingError = parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - body = append(body, bodyNode) - } - if !parser.directValueMatch(lexer.End) { - return nil, newStatementNeverEndedError(parser.currentLine(), ClassStatement) - } - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - return &ast.ClassStatement{ - Name: name, - Bases: bases, - Body: body, - }, nil -} - -func (parser *Parser) parseRaiseStatement() (*ast.RaiseStatement, *errors.Error) { - tokenizingError := parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - x, parsingError := parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - if _, ok := x.(ast.IExpression); !ok { - return nil, newNonExpressionReceivedError(parser.currentLine(), RaiseStatement) - } - return &ast.RaiseStatement{ - X: x.(ast.IExpression), - }, nil -} - -func (parser *Parser) parseTryStatement() (*ast.TryStatement, *errors.Error) { - tokenizingError := parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - if !parser.directValueMatch(lexer.NewLine) { - return nil, newSyntaxError(parser.currentLine(), TryStatement) - } - var body []ast.Node - var bodyNode ast.Node - var parsingError *errors.Error - for parser.hasNext() { - if parser.kindMatch(lexer.Separator) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - if parser.directValueMatch(lexer.End) || - parser.directValueMatch(lexer.Except) || - parser.directValueMatch(lexer.Else) || - parser.directValueMatch(lexer.Finally) { - break - } - continue - } - bodyNode, parsingError = parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - body = append(body, bodyNode) - } - var exceptBlocks []*ast.ExceptBlock - for parser.hasNext() { - if !parser.directValueMatch(lexer.Except) { - break - } - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - var targets []ast.IExpression - var target ast.Node - for parser.hasNext() { - if parser.directValueMatch(lexer.NewLine) || - parser.directValueMatch(lexer.As) { - break - } - target, parsingError = parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - if _, ok := target.(ast.IExpression); !ok { - return nil, newSyntaxError(parser.currentLine(), ExceptBlock) - } - targets = append(targets, target.(ast.IExpression)) - if parser.directValueMatch(lexer.Comma) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - } - } - var captureName *ast.Identifier - if parser.directValueMatch(lexer.As) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - newLinesRemoveError := parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - if !parser.kindMatch(lexer.IdentifierKind) { - return nil, newSyntaxError(parser.currentLine(), ExceptBlock) - } - captureName = &ast.Identifier{ - Token: parser.currentToken, - } - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - } - if !parser.directValueMatch(lexer.NewLine) { - return nil, newSyntaxError(parser.currentLine(), TryStatement) - } - var exceptBody []ast.Node - var exceptBodyNode ast.Node - for parser.hasNext() { - if parser.kindMatch(lexer.Separator) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - if parser.directValueMatch(lexer.End) || - parser.directValueMatch(lexer.Except) || - parser.directValueMatch(lexer.Else) || - parser.directValueMatch(lexer.Finally) { - break - } - continue - } - exceptBodyNode, parsingError = parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - exceptBody = append(exceptBody, exceptBodyNode) - } - exceptBlocks = append(exceptBlocks, &ast.ExceptBlock{ - Targets: targets, - CaptureName: captureName, - Body: exceptBody, - }) - } - var elseBody []ast.Node - var elseBodyNode ast.Node - if parser.directValueMatch(lexer.Else) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - if !parser.directValueMatch(lexer.NewLine) { - return nil, newSyntaxError(parser.currentLine(), ElseBlock) - } - for parser.hasNext() { - if parser.kindMatch(lexer.Separator) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - if parser.directValueMatch(lexer.End) || - parser.directValueMatch(lexer.Finally) { - break - } - continue - } - elseBodyNode, parsingError = parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - elseBody = append(elseBody, elseBodyNode) - } - } - var finallyBody []ast.Node - var finallyBodyNode ast.Node - if parser.directValueMatch(lexer.Finally) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - if !parser.directValueMatch(lexer.NewLine) { - return nil, newSyntaxError(parser.currentLine(), FinallyBlock) - } - for parser.hasNext() { - if parser.kindMatch(lexer.Separator) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - if parser.directValueMatch(lexer.End) { - break - } - continue - } - finallyBodyNode, parsingError = parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - finallyBody = append(finallyBody, finallyBodyNode) - } - } - if !parser.directValueMatch(lexer.End) { - return nil, newSyntaxError(parser.currentLine(), TryStatement) - } - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - return &ast.TryStatement{ - Body: body, - ExceptBlocks: exceptBlocks, - Else: elseBody, - Finally: finallyBody, - }, nil -} - -func (parser *Parser) parseBeginStatement() (*ast.BeginStatement, *errors.Error) { - tokenizingError := parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - if !parser.directValueMatch(lexer.NewLine) { - return nil, newSyntaxError(parser.currentLine(), BeginStatement) - } - var body []ast.Node - var bodyNode ast.Node - var parsingError *errors.Error - for parser.hasNext() { - if parser.kindMatch(lexer.Separator) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - if parser.directValueMatch(lexer.End) { - break - } - continue - } - bodyNode, parsingError = parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - body = append(body, bodyNode) - } - if !parser.directValueMatch(lexer.End) { - return nil, newStatementNeverEndedError(parser.currentLine(), BeginStatement) - } - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - return &ast.BeginStatement{ - Body: body, - }, nil -} - -func (parser *Parser) parseEndStatement() (*ast.EndStatement, *errors.Error) { - tokenizingError := parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - if !parser.directValueMatch(lexer.NewLine) { - return nil, newSyntaxError(parser.currentLine(), EndStatement) - } - var body []ast.Node - var bodyNode ast.Node - var parsingError *errors.Error - for parser.hasNext() { - if parser.kindMatch(lexer.Separator) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - if parser.directValueMatch(lexer.End) { - break - } - continue - } - bodyNode, parsingError = parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - body = append(body, bodyNode) - } - if !parser.directValueMatch(lexer.End) { - return nil, newStatementNeverEndedError(parser.currentLine(), EndStatement) - } - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - return &ast.EndStatement{ - Body: body, - }, nil -} - -func (parser *Parser) parseInterfaceStatement() (*ast.InterfaceStatement, *errors.Error) { - tokenizingError := parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - newLinesRemoveError := parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - if !parser.kindMatch(lexer.IdentifierKind) { - return nil, newSyntaxError(parser.currentLine(), InterfaceStatement) - } - name := &ast.Identifier{ - Token: parser.currentToken, - } - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - var bases []ast.IExpression - var base ast.Node - var parsingError *errors.Error - if parser.directValueMatch(lexer.OpenParentheses) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - for parser.hasNext() { - newLinesRemoveError = parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - base, parsingError = parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - if _, ok := base.(ast.IExpression); !ok { - return nil, newSyntaxError(parser.currentLine(), InterfaceStatement) - } - bases = append(bases, base.(ast.IExpression)) - newLinesRemoveError = parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - if parser.directValueMatch(lexer.Comma) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - } else if parser.directValueMatch(lexer.CloseParentheses) { - break - } else { - return nil, newSyntaxError(parser.currentLine(), InterfaceStatement) - } - } - newLinesRemoveError = parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - if !parser.directValueMatch(lexer.CloseParentheses) { - return nil, newSyntaxError(parser.currentLine(), InterfaceStatement) - } - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - } - if !parser.directValueMatch(lexer.NewLine) { - return nil, newSyntaxError(parser.currentLine(), InterfaceStatement) - } - var methods []*ast.FunctionDefinitionStatement - var node ast.Node - for parser.hasNext() { - if parser.kindMatch(lexer.Separator) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - if parser.directValueMatch(lexer.End) { - break - } - continue - } - node, parsingError = parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - if _, ok := node.(*ast.FunctionDefinitionStatement); !ok { - return nil, newNonFunctionDefinitionReceived(parser.currentLine(), InterfaceStatement) - } - methods = append(methods, node.(*ast.FunctionDefinitionStatement)) - } - newLinesRemoveError = parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - if !parser.directValueMatch(lexer.End) { - return nil, newStatementNeverEndedError(parser.currentLine(), InterfaceStatement) - } - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - return &ast.InterfaceStatement{ - Name: name, - Bases: bases, - MethodDefinitions: methods, - }, nil -} - -func (parser *Parser) parseLiteral() (ast.IExpression, *errors.Error) { - if !parser.kindMatch(lexer.Literal) && - !parser.kindMatch(lexer.Boolean) && - !parser.kindMatch(lexer.NoneType) { - return nil, newInvalidKindOfTokenError(parser.currentLine()) - } - - switch parser.currentToken.DirectValue { - case lexer.SingleQuoteString, lexer.DoubleQuoteString, lexer.ByteString, - lexer.Integer, lexer.HexadecimalInteger, lexer.BinaryInteger, lexer.OctalInteger, - lexer.Float, lexer.ScientificFloat, - lexer.True, lexer.False, lexer.None: - currentToken := parser.currentToken - tokenizingError := parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - return &ast.BasicLiteralExpression{ - Token: currentToken, - Kind: currentToken.Kind, - DirectValue: currentToken.DirectValue, - }, nil - } - return nil, newInvalidKindOfTokenError(parser.currentLine()) -} - -func (parser *Parser) parseBinaryExpression(precedence uint8) (ast.Node, *errors.Error) { - var leftHandSide ast.Node - var rightHandSide ast.Node - var parsingError *errors.Error - leftHandSide, parsingError = parser.parseUnaryExpression() - if parsingError != nil { - return nil, parsingError - } - if _, ok := leftHandSide.(ast.Statement); ok { - return leftHandSide, nil - } - for parser.hasNext() { - if !parser.kindMatch(lexer.Operator) && - !parser.kindMatch(lexer.Comparator) { - break - } - newLinesRemoveError := parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - operator := parser.currentToken - operatorPrecedence := parser.currentToken.DirectValue - if operatorPrecedence < precedence { - return leftHandSide, nil - } - tokenizingError := parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - line := parser.currentLine() - rightHandSide, parsingError = parser.parseBinaryExpression(operatorPrecedence + 1) - if parsingError != nil { - return nil, parsingError - } - if _, ok := rightHandSide.(ast.IExpression); !ok { - return nil, newNonExpressionReceivedError(line, BinaryExpression) - } - - leftHandSide = &ast.BinaryExpression{ - LeftHandSide: leftHandSide.(ast.IExpression), - Operator: operator, - RightHandSide: rightHandSide.(ast.IExpression), - } - } - return leftHandSide, nil -} - -func (parser *Parser) parseUnaryExpression() (ast.Node, *errors.Error) { - // Do something to parse Unary - if parser.kindMatch(lexer.Operator) { - switch parser.currentToken.DirectValue { - case lexer.Sub, lexer.Add, lexer.NegateBits, lexer.SignNot, lexer.Not: - operator := parser.currentToken - tokenizingError := parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - line := parser.currentLine() - x, parsingError := parser.parseUnaryExpression() - if parsingError != nil { - return nil, parsingError - } - if _, ok := x.(ast.IExpression); !ok { - return nil, newNonExpressionReceivedError(line, PointerExpression) - } - return &ast.UnaryExpression{ - Operator: operator, - X: x.(ast.IExpression), - }, nil - } - } - return parser.parsePrimaryExpression() -} - -func (parser *Parser) removeNewLines() *errors.Error { - for parser.directValueMatch(lexer.NewLine) { - tokenizingError := parser.next() - if tokenizingError != nil { - return tokenizingError - } - } - return nil -} - -func (parser *Parser) parseLambdaExpression() (*ast.LambdaExpression, *errors.Error) { - var arguments []*ast.Identifier - tokenizingError := parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - for parser.hasNext() { - if parser.directValueMatch(lexer.Colon) { - break - } - newLinesRemoveError := parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - line := parser.currentLine() - identifier, parsingError := parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - if _, ok := identifier.(*ast.Identifier); !ok { - return nil, newNonIdentifierReceivedError(line, LambdaExpression) - } - arguments = append(arguments, identifier.(*ast.Identifier)) - newLinesRemoveError = parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - if parser.directValueMatch(lexer.Comma) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - } else if !parser.directValueMatch(lexer.Colon) { - return nil, newSyntaxError(line, LambdaExpression) - } - } - newLinesRemoveError := parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - if !parser.directValueMatch(lexer.Colon) { - return nil, newSyntaxError(parser.currentLine(), LambdaExpression) - } - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - newLinesRemoveError = parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - line := parser.currentLine() - code, parsingError := parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - if _, ok := code.(ast.IExpression); !ok { - return nil, newNonExpressionReceivedError(line, LambdaExpression) - } - return &ast.LambdaExpression{ - Arguments: arguments, - Code: code.(ast.IExpression), - }, nil -} - -func (parser *Parser) parseParentheses() (ast.IExpression, *errors.Error) { - /* - This should also parse generators - */ - tokenizingError := parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - newLinesRemoveError := parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - if parser.directValueMatch(lexer.CloseParentheses) { - return nil, newSyntaxError(parser.currentLine(), ParenthesesExpression) - } - line := parser.currentLine() - firstExpression, parsingError := parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - if _, ok := firstExpression.(ast.IExpression); !ok { - return nil, newNonExpressionReceivedError(line, ParenthesesExpression) - } - newLinesRemoveError = parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - if parser.directValueMatch(lexer.For) { - return parser.parseGeneratorExpression(firstExpression.(ast.IExpression)) - } - if parser.directValueMatch(lexer.CloseParentheses) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - return &ast.ParenthesesExpression{ - X: firstExpression.(ast.IExpression), - }, nil - } - if !parser.directValueMatch(lexer.Comma) { - return nil, newSyntaxError(parser.currentLine(), ParenthesesExpression) - } - var values []ast.IExpression - values = append(values, firstExpression.(ast.IExpression)) - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - var nextValue ast.Node - for parser.hasNext() { - if parser.directValueMatch(lexer.CloseParentheses) { - break - } - newLinesRemoveError = parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - line = parser.currentLine() - nextValue, parsingError = parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - if _, ok := nextValue.(ast.IExpression); !ok { - return nil, newNonExpressionReceivedError(parser.currentLine(), ParenthesesExpression) - } - values = append(values, nextValue.(ast.IExpression)) - newLinesRemoveError = parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - if parser.directValueMatch(lexer.Comma) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - } else if !parser.directValueMatch(lexer.CloseParentheses) { - return nil, newSyntaxError(parser.currentLine(), TupleExpression) - } - } - newLinesRemoveError = parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - if !parser.directValueMatch(lexer.CloseParentheses) { - return nil, newExpressionNeverClosedError(parser.currentLine(), TupleExpression) - } - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - return &ast.TupleExpression{ - Values: values, - }, nil -} -func (parser *Parser) parseArrayExpression() (*ast.ArrayExpression, *errors.Error) { - tokenizingError := parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - newLinesRemoveError := parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - var values []ast.IExpression - for parser.hasNext() { - if parser.directValueMatch(lexer.CloseSquareBracket) { - break - } - newLinesRemoveError = parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - line := parser.currentLine() - value, parsingError := parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - if _, ok := value.(ast.IExpression); !ok { - return nil, newNonExpressionReceivedError(line, ArrayExpression) - } - values = append(values, value.(ast.IExpression)) - newLinesRemoveError = parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - if parser.directValueMatch(lexer.Comma) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - } else if !parser.directValueMatch(lexer.CloseSquareBracket) { - return nil, newSyntaxError(parser.currentLine(), ArrayExpression) - } - } - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - return &ast.ArrayExpression{ - Values: values, - }, nil -} - -func (parser *Parser) parseHashExpression() (*ast.HashExpression, *errors.Error) { - tokenizingError := parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - newLinesRemoveError := parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - var values []*ast.KeyValue - var leftHandSide ast.Node - var rightHandSide ast.Node - var parsingError *errors.Error - for parser.hasNext() { - if parser.directValueMatch(lexer.CloseBrace) { - break - } - newLinesRemoveError = parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - line := parser.currentLine() - leftHandSide, parsingError = parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - if _, ok := leftHandSide.(ast.IExpression); !ok { - return nil, newNonExpressionReceivedError(line, HashExpression) - } - newLinesRemoveError = parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - if !parser.directValueMatch(lexer.Colon) { - return nil, newSyntaxError(parser.currentLine(), HashExpression) - } - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - newLinesRemoveError = parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - line = parser.currentLine() - rightHandSide, parsingError = parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - if _, ok := rightHandSide.(ast.IExpression); !ok { - return nil, newNonExpressionReceivedError(parser.currentLine(), HashExpression) - } - values = append(values, &ast.KeyValue{ - Key: leftHandSide.(ast.IExpression), - Value: rightHandSide.(ast.IExpression), - }) - newLinesRemoveError = parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - if parser.directValueMatch(lexer.Comma) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - } - newLinesRemoveError = parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - } - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - return &ast.HashExpression{ - Values: values, - }, nil -} - -func (parser *Parser) parseWhileStatement() (*ast.WhileLoopStatement, *errors.Error) { - tokenizingError := parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - condition, parsingError := parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - if _, ok := condition.(ast.IExpression); !ok { - return nil, newSyntaxError(parser.currentLine(), WhileStatement) - } - if !parser.directValueMatch(lexer.NewLine) { - return nil, newSyntaxError(parser.currentLine(), WhileStatement) - } - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - var whileChild ast.Node - var body []ast.Node - for parser.hasNext() { - if parser.kindMatch(lexer.Separator) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - if parser.directValueMatch(lexer.End) { - break - } - continue - } - whileChild, parsingError = parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - body = append(body, whileChild) - } - if !parser.directValueMatch(lexer.End) { - return nil, newStatementNeverEndedError(parser.currentLine(), WhileStatement) - } - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - return &ast.WhileLoopStatement{ - Condition: condition.(ast.IExpression), - Body: body, - }, nil -} - -func (parser *Parser) parseDoWhileStatement() (*ast.DoWhileStatement, *errors.Error) { - tokenizingError := parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - var body []ast.Node - var bodyNode ast.Node - var parsingError *errors.Error - if !parser.directValueMatch(lexer.NewLine) { - return nil, newSyntaxError(parser.currentLine(), DoWhileStatement) - } - // Parse Body - for parser.hasNext() { - if parser.kindMatch(lexer.Separator) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - if parser.directValueMatch(lexer.While) { - break - } - continue - } - bodyNode, parsingError = parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - body = append(body, bodyNode) - } - // Parse Condition - if !parser.directValueMatch(lexer.While) { - return nil, newSyntaxError(parser.currentLine(), DoWhileStatement) - } - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - newLinesRemoveError := parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - line := parser.currentLine() - var condition ast.Node - condition, parsingError = parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - if _, ok := condition.(ast.IExpression); !ok { - return nil, newNonExpressionReceivedError(line, WhileStatement) - } - return &ast.DoWhileStatement{ - Condition: condition.(ast.IExpression), - Body: body, - }, nil -} - -func (parser *Parser) parseIfStatement() (*ast.IfStatement, *errors.Error) { - tokenizingError := parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - newLinesRemoveError := parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - line := parser.currentLine() - condition, parsingError := parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - if _, ok := condition.(ast.IExpression); !ok { - return nil, newNonExpressionReceivedError(line, IfStatement) - } - if !parser.directValueMatch(lexer.NewLine) { - return nil, newSyntaxError(line, IfStatement) - } - // Parse If - root := &ast.IfStatement{ - Condition: condition.(ast.IExpression), - Body: []ast.Node{}, - Else: []ast.Node{}, - } - var bodyNode ast.Node - for parser.hasNext() { - if parser.kindMatch(lexer.Separator) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - if parser.directValueMatch(lexer.Elif) || - parser.directValueMatch(lexer.Else) || - parser.directValueMatch(lexer.End) { - break - } - continue - } - bodyNode, parsingError = parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - root.Body = append(root.Body, bodyNode) - } - // Parse Elifs - lastCondition := root - if parser.directValueMatch(lexer.Elif) { - var elifBody []ast.Node - parsingElifLoop: - for parser.hasNext() { - if parser.kindMatch(lexer.Separator) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - if parser.directValueMatch(lexer.Else) || - parser.directValueMatch(lexer.End) { - break - } - continue - } - if !parser.directValueMatch(lexer.Elif) { - return nil, newSyntaxError(line, ElifBlock) - } - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - newLinesRemoveError = parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - var elifCondition ast.Node - elifCondition, parsingError = parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - if _, ok := elifCondition.(ast.IExpression); !ok { - return nil, newSyntaxError(line, ElifBlock) - } - if !parser.directValueMatch(lexer.NewLine) { - return nil, newSyntaxError(line, ElifBlock) - } - var elifBodyNode ast.Node - for parser.hasNext() { - if parser.kindMatch(lexer.Separator) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - if parser.directValueMatch(lexer.Else) || - parser.directValueMatch(lexer.End) || - parser.directValueMatch(lexer.Elif) { - break - } - continue - } - elifBodyNode, parsingError = parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - elifBody = append(elifBody, elifBodyNode) - } - lastCondition.Else = append( - lastCondition.Else, - &ast.IfStatement{ - Condition: elifCondition.(ast.IExpression), - Body: elifBody, - }, - ) - lastCondition = lastCondition.Else[0].(*ast.IfStatement) - if parser.directValueMatch(lexer.Else) || - parser.directValueMatch(lexer.End) { - break parsingElifLoop - } - } - } - // Parse Default - if parser.directValueMatch(lexer.Else) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - var elseBodyNode ast.Node - if !parser.directValueMatch(lexer.NewLine) { - return nil, newSyntaxError(parser.currentLine(), ElseBlock) - } - for parser.hasNext() { - if parser.kindMatch(lexer.Separator) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - if parser.directValueMatch(lexer.End) { - break - } - continue - } - elseBodyNode, parsingError = parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - lastCondition.Else = append(lastCondition.Else, elseBodyNode) - } - } - if !parser.directValueMatch(lexer.End) { - return nil, newStatementNeverEndedError(parser.currentLine(), IfStatement) - } - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - return root, nil -} - -func (parser *Parser) parseUnlessStatement() (*ast.UnlessStatement, *errors.Error) { - tokenizingError := parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - newLinesRemoveError := parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - line := parser.currentLine() - condition, parsingError := parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - if _, ok := condition.(ast.IExpression); !ok { - return nil, newNonExpressionReceivedError(line, UnlessStatement) - } - if !parser.directValueMatch(lexer.NewLine) { - return nil, newSyntaxError(line, UnlessStatement) - } - // Parse Unless - root := &ast.UnlessStatement{ - Condition: condition.(ast.IExpression), - Body: []ast.Node{}, - Else: []ast.Node{}, - } - var bodyNode ast.Node - for parser.hasNext() { - if parser.kindMatch(lexer.Separator) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - if parser.directValueMatch(lexer.Elif) || - parser.directValueMatch(lexer.Else) || - parser.directValueMatch(lexer.End) { - break - } - continue - } - bodyNode, parsingError = parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - root.Body = append(root.Body, bodyNode) - } - // Parse Elifs - lastCondition := root - if parser.directValueMatch(lexer.Elif) { - var elifBody []ast.Node - parsingElifLoop: - for parser.hasNext() { - if parser.kindMatch(lexer.Separator) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - if parser.directValueMatch(lexer.Else) || - parser.directValueMatch(lexer.End) { - break - } - continue - } - if !parser.directValueMatch(lexer.Elif) { - return nil, newSyntaxError(line, ElifBlock) - } - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - newLinesRemoveError = parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - var elifCondition ast.Node - elifCondition, parsingError = parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - if _, ok := elifCondition.(ast.IExpression); !ok { - return nil, newSyntaxError(line, ElifBlock) - } - if !parser.directValueMatch(lexer.NewLine) { - return nil, newSyntaxError(line, ElifBlock) - } - var elifBodyNode ast.Node - for parser.hasNext() { - if parser.kindMatch(lexer.Separator) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - if parser.directValueMatch(lexer.Else) || - parser.directValueMatch(lexer.End) || - parser.directValueMatch(lexer.Elif) { - break - } - continue - } - elifBodyNode, parsingError = parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - elifBody = append(elifBody, elifBodyNode) - } - lastCondition.Else = append( - lastCondition.Else, - &ast.UnlessStatement{ - Condition: elifCondition.(ast.IExpression), - Body: elifBody, - }, - ) - lastCondition = lastCondition.Else[0].(*ast.UnlessStatement) - if parser.directValueMatch(lexer.Else) || - parser.directValueMatch(lexer.End) { - break parsingElifLoop - } - } - } - // Parse Default - if parser.directValueMatch(lexer.Else) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - var elseBodyNode ast.Node - if !parser.directValueMatch(lexer.NewLine) { - return nil, newSyntaxError(parser.currentLine(), ElseBlock) - } - for parser.hasNext() { - if parser.kindMatch(lexer.Separator) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - if parser.directValueMatch(lexer.End) { - break - } - continue - } - elseBodyNode, parsingError = parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - lastCondition.Else = append(lastCondition.Else, elseBodyNode) - } - } - if !parser.directValueMatch(lexer.End) { - return nil, newStatementNeverEndedError(parser.currentLine(), UnlessStatement) - } - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - return root, nil -} - -func (parser *Parser) parseSwitchStatement() (*ast.SwitchStatement, *errors.Error) { - tokenizingError := parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - newLinesRemoveError := parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - line := parser.currentLine() - target, parsingError := parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - if _, ok := target.(ast.IExpression); !ok { - return nil, newNonExpressionReceivedError(line, SwitchStatement) - } - if !parser.directValueMatch(lexer.NewLine) { - return nil, newSyntaxError(line, SwitchStatement) - } - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - // parse Cases - var caseBlocks []*ast.CaseBlock - if parser.directValueMatch(lexer.Case) { - for parser.hasNext() { - if parser.directValueMatch(lexer.Default) || - parser.directValueMatch(lexer.End) { - break - } - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - newLinesRemoveError = parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - var cases []ast.IExpression - var caseTarget ast.Node - for parser.hasNext() { - caseTarget, parsingError = parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - if _, ok := caseTarget.(ast.IExpression); !ok { - return nil, newNonExpressionReceivedError(line, CaseBlock) - } - cases = append(cases, caseTarget.(ast.IExpression)) - if parser.directValueMatch(lexer.NewLine) { - break - } else if parser.directValueMatch(lexer.Comma) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - } else { - return nil, newSyntaxError(line, CaseBlock) - } - } - if !parser.directValueMatch(lexer.NewLine) { - return nil, newSyntaxError(parser.currentLine(), CaseBlock) - } - // Targets Body - var caseBody []ast.Node - var caseBodyNode ast.Node - for parser.hasNext() { - if parser.kindMatch(lexer.Separator) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - if parser.directValueMatch(lexer.Case) || - parser.directValueMatch(lexer.Default) || - parser.directValueMatch(lexer.End) { - break - } - continue - } - caseBodyNode, parsingError = parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - caseBody = append(caseBody, caseBodyNode) - } - // Targets block - caseBlocks = append(caseBlocks, &ast.CaseBlock{ - Cases: cases, - Body: caseBody, - }) - } - } - // Parse Default - var defaultBody []ast.Node - if parser.directValueMatch(lexer.Default) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - if !parser.directValueMatch(lexer.NewLine) { - return nil, newSyntaxError(parser.currentLine(), DefaultBlock) - } - var defaultBodyNode ast.Node - for parser.hasNext() { - if parser.kindMatch(lexer.Separator) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - if parser.directValueMatch(lexer.End) { - break - } - continue - } - defaultBodyNode, parsingError = parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - defaultBody = append(defaultBody, defaultBodyNode) - } - } - // Finally detect valid end - if !parser.directValueMatch(lexer.End) { - return nil, newStatementNeverEndedError(parser.currentLine(), SwitchStatement) - } - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - return &ast.SwitchStatement{ - Target: target.(ast.IExpression), - CaseBlocks: caseBlocks, - Default: defaultBody, - }, nil -} - -func (parser *Parser) parseReturnStatement() (*ast.ReturnStatement, *errors.Error) { - tokenizingError := parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - newLinesRemoveError := parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - var results []ast.IExpression - for parser.hasNext() { - if parser.kindMatch(lexer.Separator) || parser.kindMatch(lexer.EOF) { - break - } - line := parser.currentLine() - result, parsingError := parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - if _, ok := result.(ast.IExpression); !ok { - return nil, newNonExpressionReceivedError(line, ReturnStatement) - } - results = append(results, result.(ast.IExpression)) - if parser.directValueMatch(lexer.Comma) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - } else if !(parser.kindMatch(lexer.Separator) || parser.kindMatch(lexer.EOF)) { - return nil, newSyntaxError(parser.currentLine(), ReturnStatement) - } - } - return &ast.ReturnStatement{ - Results: results, - }, nil -} - -func (parser *Parser) parseYieldStatement() (*ast.YieldStatement, *errors.Error) { - tokenizingError := parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - newLinesRemoveError := parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - var results []ast.IExpression - for parser.hasNext() { - if parser.kindMatch(lexer.Separator) || parser.kindMatch(lexer.EOF) { - break - } - line := parser.currentLine() - result, parsingError := parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - if _, ok := result.(ast.IExpression); !ok { - return nil, newNonExpressionReceivedError(line, YieldStatement) - } - results = append(results, result.(ast.IExpression)) - if parser.directValueMatch(lexer.Comma) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - } else if !(parser.kindMatch(lexer.Separator) || parser.kindMatch(lexer.EOF)) { - return nil, newSyntaxError(parser.currentLine(), YieldStatement) - } - } - return &ast.YieldStatement{ - Results: results, - }, nil -} - -func (parser *Parser) parseContinueStatement() (*ast.ContinueStatement, *errors.Error) { - tokenizingError := parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - return &ast.ContinueStatement{}, nil -} - -func (parser *Parser) parseBreakStatement() (*ast.BreakStatement, *errors.Error) { - tokenizingError := parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - return &ast.BreakStatement{}, nil -} - -func (parser *Parser) parseRedoStatement() (*ast.RedoStatement, *errors.Error) { - tokenizingError := parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - return &ast.RedoStatement{}, nil -} - -func (parser *Parser) parsePassStatement() (*ast.PassStatement, *errors.Error) { - tokenizingError := parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - return &ast.PassStatement{}, nil -} - -func (parser *Parser) parseOperand() (ast.Node, *errors.Error) { - switch parser.currentToken.Kind { - case lexer.Literal, lexer.Boolean, lexer.NoneType: - return parser.parseLiteral() - case lexer.IdentifierKind: - identifier := parser.currentToken - - tokenizingError := parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - return &ast.Identifier{ - Token: identifier, - }, nil - case lexer.Keyboard: - switch parser.currentToken.DirectValue { - case lexer.Lambda: - return parser.parseLambdaExpression() - case lexer.While: - return parser.parseWhileStatement() - case lexer.For: - return parser.parseForStatement() - case lexer.Until: - return parser.parseUntilStatement() - case lexer.If: - return parser.parseIfStatement() - case lexer.Unless: - return parser.parseUnlessStatement() - case lexer.Switch: - return parser.parseSwitchStatement() - case lexer.Module: - return parser.parseModuleStatement() - case lexer.Def: - return parser.parseFunctionDefinitionStatement() - case lexer.Interface: - return parser.parseInterfaceStatement() - case lexer.Class: - return parser.parseClassStatement() - case lexer.Raise: - return parser.parseRaiseStatement() - case lexer.Try: - return parser.parseTryStatement() - case lexer.Return: - return parser.parseReturnStatement() - case lexer.Yield: - return parser.parseYieldStatement() - case lexer.Continue: - return parser.parseContinueStatement() - case lexer.Break: - return parser.parseBreakStatement() - case lexer.Redo: - return parser.parseRedoStatement() - case lexer.Pass: - return parser.parsePassStatement() - case lexer.Do: - return parser.parseDoWhileStatement() - } - case lexer.Punctuation: - switch parser.currentToken.DirectValue { - case lexer.OpenParentheses: - return parser.parseParentheses() - case lexer.OpenSquareBracket: // Parse Arrays - return parser.parseArrayExpression() - case lexer.OpenBrace: // Parse Dictionaries - return parser.parseHashExpression() - } - } - return nil, errors.New(parser.currentLine(), "Unknown Token", errors.ParsingError) -} - -func (parser *Parser) parseSelectorExpression(expression ast.IExpression) (*ast.SelectorExpression, *errors.Error) { - selector := expression - for parser.hasNext() { - if !parser.directValueMatch(lexer.Dot) { - break - } - tokenizingError := parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - identifier := parser.currentToken - if identifier.Kind != lexer.IdentifierKind { - return nil, newSyntaxError(parser.currentLine(), SelectorExpression) - } - selector = &ast.SelectorExpression{ - X: selector, - Identifier: &ast.Identifier{ - Token: identifier, - }, - } - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - } - return selector.(*ast.SelectorExpression), nil -} - -func (parser *Parser) parseMethodInvocationExpression(expression ast.IExpression) (*ast.MethodInvocationExpression, *errors.Error) { - var arguments []ast.IExpression - // The first token is open parentheses - tokenizingError := parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - newLinesRemoveError := parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - for parser.hasNext() { - if parser.directValueMatch(lexer.CloseParentheses) { - break - } - newLinesRemoveError = parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - line := parser.currentLine() - argument, parsingError := parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - if _, ok := argument.(ast.IExpression); !ok { - return nil, newNonExpressionReceivedError(line, MethodInvocationExpression) - } - arguments = append(arguments, argument.(ast.IExpression)) - newLinesRemoveError = parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - if parser.directValueMatch(lexer.Comma) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - } - } - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - return &ast.MethodInvocationExpression{ - Function: expression, - Arguments: arguments, - }, nil -} - -func (parser *Parser) parseIndexExpression(expression ast.IExpression) (*ast.IndexExpression, *errors.Error) { - tokenizationError := parser.next() - if tokenizationError != nil { - return nil, tokenizationError - } - newLinesRemoveError := parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - // var rightIndex ast.Node - line := parser.currentLine() - index, parsingError := parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - if _, ok := index.(ast.IExpression); !ok { - return nil, newNonExpressionReceivedError(line, IndexExpression) - } - newLinesRemoveError = parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - if !parser.directValueMatch(lexer.CloseSquareBracket) { - return nil, newSyntaxError(parser.currentLine(), IndexExpression) - } - tokenizationError = parser.next() - if tokenizationError != nil { - return nil, tokenizationError - } - return &ast.IndexExpression{ - Source: expression, - Index: index.(ast.IExpression), - }, nil -} - -func (parser *Parser) parseIfOneLinerExpression(result ast.IExpression) (*ast.IfOneLinerExpression, *errors.Error) { - tokenizingError := parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - newLinesRemoveError := parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - line := parser.currentLine() - condition, parsingError := parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - if _, ok := condition.(ast.IExpression); !ok { - return nil, newNonExpressionReceivedError(line, IfOneLinerExpression) - } - if !parser.directValueMatch(lexer.Else) { - return &ast.IfOneLinerExpression{ - Result: result, - Condition: condition.(ast.IExpression), - ElseResult: nil, - }, nil - } - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - newLinesRemoveError = parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - var elseResult ast.Node - elseResult, parsingError = parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - if _, ok := elseResult.(ast.IExpression); !ok { - return nil, newNonExpressionReceivedError(line, OneLineElseBlock) - } - return &ast.IfOneLinerExpression{ - Result: result, - Condition: condition.(ast.IExpression), - ElseResult: elseResult.(ast.IExpression), - }, nil -} - -func (parser *Parser) parseUnlessOneLinerExpression(result ast.IExpression) (*ast.UnlessOneLinerExpression, *errors.Error) { - tokenizingError := parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - newLinesRemoveError := parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - line := parser.currentLine() - condition, parsingError := parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - if _, ok := condition.(ast.IExpression); !ok { - return nil, newNonExpressionReceivedError(line, UnlessOneLinerExpression) - } - if !parser.directValueMatch(lexer.Else) { - return &ast.UnlessOneLinerExpression{ - Result: result, - Condition: condition.(ast.IExpression), - ElseResult: nil, - }, nil - } - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - newLinesRemoveError = parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - var elseResult ast.Node - line = parser.currentLine() - elseResult, parsingError = parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - if _, ok := condition.(ast.IExpression); !ok { - return nil, newNonExpressionReceivedError(line, OneLineElseBlock) - } - return &ast.UnlessOneLinerExpression{ - Result: result, - Condition: condition.(ast.IExpression), - ElseResult: elseResult.(ast.IExpression), - }, nil -} - -func (parser *Parser) parseGeneratorExpression(operation ast.IExpression) (*ast.GeneratorExpression, *errors.Error) { - tokenizingError := parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - newLinesRemoveError := parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - var variables []*ast.Identifier - numberOfVariables := 0 - for parser.hasNext() { - if parser.directValueMatch(lexer.In) { - break - } - newLinesRemoveError = parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - if !parser.kindMatch(lexer.IdentifierKind) { - return nil, newSyntaxError(parser.currentLine(), GeneratorExpression) - } - variables = append(variables, &ast.Identifier{ - Token: parser.currentToken, - }) - numberOfVariables++ - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - newLinesRemoveError = parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - if parser.directValueMatch(lexer.Comma) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - } - } - if numberOfVariables == 0 { - return nil, newSyntaxError(parser.currentLine(), GeneratorExpression) - } - if !parser.directValueMatch(lexer.In) { - return nil, newSyntaxError(parser.currentLine(), GeneratorExpression) - } - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - newLinesRemoveError = parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - line := parser.currentLine() - source, parsingError := parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - if _, ok := source.(ast.IExpression); !ok { - return nil, newNonExpressionReceivedError(line, GeneratorExpression) - } - newLinesRemoveError = parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - // Finally detect the closing parentheses - if !parser.directValueMatch(lexer.CloseParentheses) { - return nil, newSyntaxError(line, GeneratorExpression) - } - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - return &ast.GeneratorExpression{ - Operation: operation, - Receivers: variables, - Source: source.(ast.IExpression), - }, nil -} - -func (parser *Parser) parseAssignmentStatement(leftHandSide ast.IExpression) (*ast.AssignStatement, *errors.Error) { - assignmentToken := parser.currentToken - tokenizingError := parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - newLinesRemoveError := parser.removeNewLines() - if newLinesRemoveError != nil { - return nil, newLinesRemoveError - } - line := parser.currentLine() - rightHandSide, parsingError := parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - if _, ok := rightHandSide.(ast.IExpression); !ok { - return nil, newNonExpressionReceivedError(line, AssignStatement) - } - return &ast.AssignStatement{ - LeftHandSide: leftHandSide, - AssignOperator: assignmentToken, - RightHandSide: rightHandSide.(ast.IExpression), - }, nil -} - -func (parser *Parser) parsePrimaryExpression() (ast.Node, *errors.Error) { - var parsedNode ast.Node - var parsingError *errors.Error - parsedNode, parsingError = parser.parseOperand() - if parsingError != nil { - return nil, parsingError - } -expressionPendingLoop: - for { - switch parser.currentToken.DirectValue { - case lexer.Dot: // Is selector - parsedNode, parsingError = parser.parseSelectorExpression(parsedNode.(ast.IExpression)) - case lexer.OpenParentheses: // Is function Call - parsedNode, parsingError = parser.parseMethodInvocationExpression(parsedNode.(ast.IExpression)) - case lexer.OpenSquareBracket: // Is indexing - parsedNode, parsingError = parser.parseIndexExpression(parsedNode.(ast.IExpression)) - case lexer.If: // One line If - parsedNode, parsingError = parser.parseIfOneLinerExpression(parsedNode.(ast.IExpression)) - case lexer.Unless: // One line Unless - parsedNode, parsingError = parser.parseUnlessOneLinerExpression(parsedNode.(ast.IExpression)) - default: - if parser.kindMatch(lexer.Assignment) { - parsedNode, parsingError = parser.parseAssignmentStatement(parsedNode.(ast.IExpression)) - } - break expressionPendingLoop - } - } - if parsingError != nil { - return nil, parsingError - } - return parsedNode, nil -} - -func (parser *Parser) Parse() (*ast.Program, *errors.Error) { - result := &ast.Program{ - Begin: nil, - End: nil, - Body: nil, - } - tokenizingError := parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - var beginStatement *ast.BeginStatement - var endStatement *ast.EndStatement - var parsedExpression ast.Node - var parsingError *errors.Error - for parser.hasNext() { - if parser.kindMatch(lexer.Separator) { - tokenizingError = parser.next() - if tokenizingError != nil { - return nil, tokenizingError - } - continue - } - if parser.directValueMatch(lexer.BEGIN) { - beginStatement, parsingError = parser.parseBeginStatement() - if result.Begin != nil { - return nil, errors.New(parser.currentLine(), "multiple declarations of BEGIN statement at line", errors.ParsingError) - } - result.Begin = beginStatement - } else if parser.directValueMatch(lexer.END) { - endStatement, parsingError = parser.parseEndStatement() - if result.End != nil { - return nil, errors.New(parser.currentLine(), "multiple declarations of END statement at line", errors.ParsingError) - } - result.End = endStatement - } else { - parsedExpression, parsingError = parser.parseBinaryExpression(0) - if parsingError != nil { - return nil, parsingError - } - result.Body = append(result.Body, parsedExpression) - } - } - parser.complete = true - return result, nil -} - -func NewParser(lexer_ *lexer.Lexer) *Parser { - return &Parser{ - lexer: lexer_, - complete: false, - currentToken: nil, - } -} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/errors/error.go b/vendor/github.com/shoriwe/gplasma/pkg/errors/error.go deleted file mode 100644 index b2c708a..0000000 --- a/vendor/github.com/shoriwe/gplasma/pkg/errors/error.go +++ /dev/null @@ -1,47 +0,0 @@ -package errors - -import ( - "errors" - "fmt" -) - -// Compiling Errors -const ( - LexingError = "LexingError" - ParsingError = "ParsingError" - SyntaxError = "SyntaxError" -) - -type Error struct { - type_ string - message string - line int -} - -func (plasmaError *Error) Type() string { - return plasmaError.type_ -} - -func (plasmaError *Error) Message() string { - return plasmaError.message -} - -func (plasmaError *Error) String() string { - return fmt.Sprintf("%s: %s at line %d", plasmaError.type_, plasmaError.message, plasmaError.line) -} - -func (plasmaError *Error) Line() int { - return plasmaError.line -} - -func (plasmaError *Error) Error() error { - return errors.New(plasmaError.String()) -} - -func New(line int, message string, type_ string) *Error { - return &Error{ - type_: type_, - message: message, - line: line, - } -} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/errors/runtime_errors.go b/vendor/github.com/shoriwe/gplasma/pkg/errors/runtime_errors.go deleted file mode 100644 index fba1329..0000000 --- a/vendor/github.com/shoriwe/gplasma/pkg/errors/runtime_errors.go +++ /dev/null @@ -1,40 +0,0 @@ -package errors - -import ( - "fmt" -) - -// This should be changed -const ( - UnknownLine = 0 -) - -// Errors Types -const ( - UnknownVmOperationError = "UnknownVMOperationError" - NameNotFoundError = "NameNotFoundError" - IndexError = "IndexError" - GoRuntimeError = "GoRuntimeError" -) - -// Errors Messages -const ( - UnknownTokenKindMessage = "Unknown token kind" - NameNotFoundMessage = "Name not found" -) - -func NewUnknownTokenKindError(line int) *Error { - return New(line, UnknownTokenKindMessage, LexingError) -} - -func NewIndexOutOfRangeError(line int, length int, index int) *Error { - return New(line, fmt.Sprintf("index %d out of bound for a %d container", index, length), IndexError) -} - -func NewNameNotFoundError() *Error { - return New(UnknownLine, NameNotFoundMessage, NameNotFoundError) -} - -func NewUnknownVMOperationError(operation uint8) *Error { - return New(UnknownLine, fmt.Sprintf("unknown operation with value %d", operation), UnknownVmOperationError) -} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/compiler/lexer/ToDo.md b/vendor/github.com/shoriwe/gplasma/pkg/lexer/ToDo.md similarity index 99% rename from vendor/github.com/shoriwe/gplasma/pkg/compiler/lexer/ToDo.md rename to vendor/github.com/shoriwe/gplasma/pkg/lexer/ToDo.md index 961af1a..5d7e2b5 100644 --- a/vendor/github.com/shoriwe/gplasma/pkg/compiler/lexer/ToDo.md +++ b/vendor/github.com/shoriwe/gplasma/pkg/lexer/ToDo.md @@ -29,7 +29,7 @@ - [X] Braces - [X] Square Brackets -## Keyboards +## Keywords - [X] Pass - [X] super diff --git a/vendor/github.com/shoriwe/gplasma/pkg/lexer/detect-kind.go b/vendor/github.com/shoriwe/gplasma/pkg/lexer/detect-kind.go new file mode 100644 index 0000000..287226f --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/lexer/detect-kind.go @@ -0,0 +1,90 @@ +package lexer + +func (lexer *Lexer) detectKindAndDirectValue() (Kind, DirectValue) { + s := lexer.currentToken.String() + switch s { + case PassString: + return Keyword, Pass + case SuperString: + return Keyword, Super + case DeleteString: + return Keyword, Delete + case EndString: + return Keyword, End + case IfString: + return Keyword, If + case UnlessString: + return Keyword, Unless + case ElseString: + return Keyword, Else + case ElifString: + return Keyword, Elif + case WhileString: + return Keyword, While + case DoString: + return Keyword, Do + case ForString: + return Keyword, For + case UntilString: + return Keyword, Until + case SwitchString: + return Keyword, Switch + case CaseString: + return Keyword, Case + case DefaultString: + return Keyword, Default + case YieldString: + return Keyword, Yield + case ReturnString: + return Keyword, Return + case ContinueString: + return Keyword, Continue + case BreakString: + return Keyword, Break + case ModuleString: + return Keyword, Module + case DefString: + return Keyword, Def + case GeneratorString: + return Keyword, Generator + case LambdaString: + return Keyword, Lambda + case InterfaceString: + return Keyword, Interface + case ClassString: + return Keyword, Class + case AndString: + return Comparator, And + case OrString: + return Comparator, Or + case XorString: + return Comparator, Xor + case InString: + return Comparator, In + case IsString: + return Comparator, Is + case ImplementsString: + return Comparator, Implements + case BEGINString: + return Keyword, BEGIN + case ENDString: + return Keyword, END + case NotString: // Unary operator + return Operator, Not + case TrueString: + return Boolean, True + case FalseString: + return Boolean, False + case NoneString: + return NoneType, None + case DeferString: + return Keyword, Defer + default: + if identifierCheck.MatchString(s) { + return IdentifierKind, InvalidDirectValue + } else if junkKindCheck.MatchString(s) { + return JunkKind, InvalidDirectValue + } + } + return Unknown, InvalidDirectValue +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/lexer/kinds.go b/vendor/github.com/shoriwe/gplasma/pkg/lexer/kinds.go new file mode 100644 index 0000000..d80a2b9 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/lexer/kinds.go @@ -0,0 +1,25 @@ +package lexer + +/* + Token Kinds +*/ + +type Kind uint8 + +const ( + Unknown Kind = iota + Comment + Whitespace + Literal + IdentifierKind + JunkKind + Separator + Punctuation + Assignment + Comparator + Operator + Keyword + Boolean + NoneType + EOF +) diff --git a/vendor/github.com/shoriwe/gplasma/pkg/lexer/lexer.go b/vendor/github.com/shoriwe/gplasma/pkg/lexer/lexer.go new file mode 100644 index 0000000..7e526e9 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/lexer/lexer.go @@ -0,0 +1,234 @@ +package lexer + +import ( + "errors" + "github.com/shoriwe/gplasma/pkg/reader" + "regexp" +) + +var ( + identifierCheck = regexp.MustCompile("(?m)^[a-zA-Z_]+[a-zA-Z0-9_]*$") + junkKindCheck = regexp.MustCompile("(?m)^\\00+$") +) + +type Lexer struct { + currentToken *Token + lastToken *Token + reader reader.Reader + complete bool +} + +var ( + CRLFInvalid = errors.New("invalid CRLF") + LineEscapeIncomplete = errors.New("incomplete line escape") +) + +func (lexer *Lexer) HasNext() bool { + return !lexer.complete +} + +func (lexer *Lexer) next() (*Token, error) { + lexer.currentToken = &Token{ + Contents: nil, + DirectValue: InvalidDirectValue, + Kind: EOF, + Line: lexer.reader.Line(), + Index: lexer.reader.Index(), + } + if !lexer.reader.HasNext() { + lexer.complete = true + return lexer.currentToken, nil + } + var tokenizingError error + char := lexer.reader.Char() + lexer.currentToken.append(char) + lexer.reader.Next() + switch char { + case '\r': + if lexer.reader.Char() != NewLineChar { + return nil, CRLFInvalid + } + lexer.reader.Next() + lexer.currentToken.append(char, '\n') + lexer.currentToken.Kind = Separator + lexer.currentToken.DirectValue = NewLine + case NewLineChar: + lexer.currentToken.Kind = Separator + lexer.currentToken.DirectValue = NewLine + case SemiColonChar: + + lexer.currentToken.Kind = Separator + lexer.currentToken.DirectValue = SemiColon + case ColonChar: + + lexer.currentToken.DirectValue = Colon + lexer.currentToken.Kind = Punctuation + case CommaChar: + + lexer.currentToken.DirectValue = Comma + lexer.currentToken.Kind = Punctuation + case OpenParenthesesChar: + + lexer.currentToken.DirectValue = OpenParentheses + lexer.currentToken.Kind = Punctuation + case CloseParenthesesChar: + + lexer.currentToken.DirectValue = CloseParentheses + lexer.currentToken.Kind = Punctuation + case OpenSquareBracketChar: + + lexer.currentToken.DirectValue = OpenSquareBracket + lexer.currentToken.Kind = Punctuation + case CloseSquareBracketChar: + + lexer.currentToken.DirectValue = CloseSquareBracket + lexer.currentToken.Kind = Punctuation + case OpenBraceChar: + + lexer.currentToken.DirectValue = OpenBrace + lexer.currentToken.Kind = Punctuation + case CloseBraceChar: + + lexer.currentToken.DirectValue = CloseBrace + lexer.currentToken.Kind = Punctuation + case DollarSignChar: + + lexer.currentToken.DirectValue = DollarSign + lexer.currentToken.Kind = Punctuation + case DotChar: + + lexer.currentToken.DirectValue = Dot + lexer.currentToken.Kind = Punctuation + case WhiteSpaceChar: + + lexer.currentToken.DirectValue = Blank + lexer.currentToken.Kind = Whitespace + case TabChar: + + lexer.currentToken.DirectValue = Blank + lexer.currentToken.Kind = Whitespace + case CommentChar: + + lexer.tokenizeComment() + case '\'', '"', '`': + + tokenizingError = lexer.tokenizeStringLikeExpressions(char) + case '1', '2', '3', '4', '5', '6', '7', '8', '9', '0': + + tokenizingError = lexer.tokenizeNumeric() + case StarChar: + + lexer.tokenizeRepeatableOperator(Star, Operator, PowerOf, Operator, StarAssign, Assignment, PowerOfAssign, Assignment) + case DivChar: + + lexer.tokenizeRepeatableOperator(Div, Operator, FloorDiv, Operator, DivAssign, Assignment, FloorDivAssign, Assignment) + case LessThanChar: + + lexer.tokenizeRepeatableOperator(LessThan, Comparator, BitwiseLeft, Operator, LessOrEqualThan, Comparator, BitwiseLeftAssign, Assignment) + case GreatThanChar: + + lexer.tokenizeRepeatableOperator(GreaterThan, Comparator, BitwiseRight, Operator, GreaterOrEqualThan, Comparator, BitwiseRightAssign, Assignment) + case AddChar: + + lexer.tokenizeSingleOperator(Add, Operator, AddAssign, Assignment) + case SubChar: + + lexer.tokenizeSingleOperator(Sub, Operator, SubAssign, Assignment) + case ModulusChar: + + lexer.tokenizeSingleOperator(Modulus, Operator, ModulusAssign, Assignment) + case BitwiseXorChar: + + lexer.tokenizeSingleOperator(BitwiseXor, Operator, BitwiseXorAssign, Assignment) + case BitWiseAndChar: + + lexer.tokenizeSingleOperator(BitwiseAnd, Operator, BitwiseAndAssign, Assignment) + case BitwiseOrChar: + lexer.tokenizeSingleOperator(BitwiseOr, Operator, BitwiseOrAssign, Assignment) + case SignNotChar: + lexer.tokenizeSingleOperator(SignNot, Operator, NotEqual, Comparator) + case NegateBitsChar: + lexer.currentToken.Kind = Operator + lexer.currentToken.DirectValue = NegateBits + case EqualsChar: + lexer.tokenizeSingleOperator(Assign, Assignment, Equals, Comparator) + case BackSlashChar: + + if !lexer.reader.HasNext() { + return nil, LineEscapeIncomplete + } + nextChar := lexer.reader.Char() + if nextChar != '\n' { + return nil, LineEscapeIncomplete + } + lexer.currentToken.append('\n') + lexer.reader.Next() + + default: + if char != 'b' || !lexer.reader.HasNext() { + lexer.tokenizeWord() + break + } + nextChar := lexer.reader.Char() + if nextChar != '\'' && nextChar != '"' { + lexer.tokenizeWord() + break + } + lexer.reader.Next() + lexer.currentToken.append(nextChar) + tokenizingError = lexer.tokenizeStringLikeExpressions(nextChar) + if lexer.currentToken.DirectValue != InvalidDirectValue { + lexer.currentToken.DirectValue = ByteString + } + break + } + return lexer.currentToken, tokenizingError +} + +/* + This function will yield just the necessary token, this means not repeated separators +*/ +func (lexer *Lexer) Next() (*Token, error) { + token, tokenizingError := lexer.next() + if tokenizingError != nil { + return nil, tokenizingError + } + if token.Kind == JunkKind { + return lexer.Next() + } + if token.Kind == Comment { + return lexer.Next() + } + if token.Kind == Whitespace { + return lexer.Next() + } + if token.Kind == Separator { + if lexer.lastToken == nil { + return lexer.Next() + } + switch lexer.lastToken.Kind { + case Separator: + return lexer.Next() + case Operator, Comparator: + return lexer.Next() + default: + break + } + switch lexer.lastToken.DirectValue { + case Comma, OpenParentheses, OpenSquareBracket, OpenBrace: + return lexer.Next() + default: + break + } + } + lexer.lastToken = token + return token, nil +} + +func NewLexer(codeReader reader.Reader) *Lexer { + return &Lexer{ + lastToken: nil, + reader: codeReader, + complete: false, + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/compiler/lexer/token.go b/vendor/github.com/shoriwe/gplasma/pkg/lexer/token.go similarity index 57% rename from vendor/github.com/shoriwe/gplasma/pkg/compiler/lexer/token.go rename to vendor/github.com/shoriwe/gplasma/pkg/lexer/token.go index c24e2d9..ac37f4a 100644 --- a/vendor/github.com/shoriwe/gplasma/pkg/compiler/lexer/token.go +++ b/vendor/github.com/shoriwe/gplasma/pkg/lexer/token.go @@ -1,25 +1,11 @@ package lexer -/* - Token Kinds -*/ +type DirectValue uint8 const ( - Unknown uint8 = iota - PendingEscape - Comment - Whitespace - Literal - Tab - IdentifierKind - JunkKind - Separator - Punctuation - Assignment - Comparator - Operator - SingleQuoteString + SingleQuoteString DirectValue = iota DoubleQuoteString + ByteString Integer HexadecimalInteger BinaryInteger @@ -27,11 +13,6 @@ const ( Float ScientificFloat CommandOutput - ByteString - Keyboard - Boolean - NoneType - EOF Comma Colon @@ -40,11 +21,11 @@ const ( Pass Super + Delete + Defer End If Unless - As - Raise Else Elif While @@ -58,24 +39,19 @@ const ( Return Continue Break - Redo Module Def + Generator Lambda Interface Class - Try - Except - Finally BEGIN END - Context Assign - NegateBitsAssign BitwiseOrAssign BitwiseXorAssign - BitWiseAndAssign + BitwiseAndAssign BitwiseLeftAssign BitwiseRightAssign AddAssign @@ -95,6 +71,8 @@ const ( Xor In + Is + Implements Equals NotEqual GreaterThan @@ -104,7 +82,7 @@ const ( BitwiseOr BitwiseXor - BitWiseAnd + BitwiseAnd BitwiseLeft BitwiseRight @@ -128,6 +106,9 @@ const ( CloseBrace DollarSign Dot + + InvalidDirectValue + Blank ) /* @@ -135,16 +116,24 @@ const ( */ type Token struct { - String string - DirectValue uint8 - Kind uint8 + Contents []rune + DirectValue DirectValue + Kind Kind Line int Column int Index int } +func (token *Token) String() string { + return string(token.Contents) +} + +func (token *Token) append(r ...rune) { + token.Contents = append(token.Contents, r...) +} + /* - Keyboards + Keywords */ var ( @@ -178,44 +167,43 @@ var ( CommentChar = '#' BackSlashChar = '\\' - PassString = "pass" - SuperString = "super" - EndString = "end" - IfString = "if" - UnlessString = "unless" - ElseString = "else" - ElifString = "elif" - WhileString = "while" - DoString = "do" - ForString = "for" - UntilString = "until" - SwitchString = "switch" - CaseString = "case" - DefaultString = "default" - YieldString = "yield" - ReturnString = "return" - ContinueString = "continue" - BreakString = "break" - RedoString = "redo" - ModuleString = "module" - DefString = "def" - LambdaString = "lambda" - InterfaceString = "interface" - ClassString = "class" - TryString = "try" - ExceptString = "except" - FinallyString = "finally" - AndString = "and" - OrString = "or" - XorString = "xor" - InString = "in" - BEGINString = "BEGIN" - ENDString = "END" - NotString = "not" - TrueString = "True" - FalseString = "False" - NoneString = "None" - ContextString = "context" - RaiseString = "raise" - AsString = "as" + PassString = "pass" + SuperString = "super" + DeleteString = "delete" + DeferString = "defer" + RequireString = "require" + EndString = "end" + IfString = "if" + UnlessString = "unless" + ElseString = "else" + ElifString = "elif" + WhileString = "while" + DoString = "do" + ForString = "for" + UntilString = "until" + SwitchString = "switch" + CaseString = "case" + DefaultString = "default" + YieldString = "yield" + ReturnString = "return" + ContinueString = "continue" + BreakString = "break" + ModuleString = "module" + DefString = "def" + GeneratorString = "gen" + LambdaString = "lambda" + InterfaceString = "interface" + ClassString = "class" + AndString = "and" + OrString = "or" + XorString = "xor" + InString = "in" + IsString = "is" + ImplementsString = "implements" + BEGINString = "BEGIN" + ENDString = "END" + NotString = "not" + TrueString = "true" + FalseString = "false" + NoneString = "none" ) diff --git a/vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-binary.go b/vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-binary.go new file mode 100644 index 0000000..8dd33d1 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-binary.go @@ -0,0 +1,33 @@ +package lexer + +import "errors" + +var ( + BinaryInvalidSyntax = errors.New("invalid binary integer syntax") +) + +func (lexer *Lexer) tokenizeBinary() error { + if !lexer.reader.HasNext() { + lexer.currentToken.Kind = Literal + lexer.currentToken.DirectValue = InvalidDirectValue + return BinaryInvalidSyntax + } + nextDigit := lexer.reader.Char() + if !(nextDigit == '0' || nextDigit == '1') { + lexer.currentToken.Kind = Literal + lexer.currentToken.DirectValue = InvalidDirectValue + return BinaryInvalidSyntax + } + lexer.reader.Next() + lexer.currentToken.append(nextDigit) + for ; lexer.reader.HasNext(); lexer.reader.Next() { + nextDigit = lexer.reader.Char() + if !(nextDigit == '0' || nextDigit == '1') && nextDigit != '_' { + break + } + lexer.currentToken.append(nextDigit) + } + lexer.currentToken.Kind = Literal + lexer.currentToken.DirectValue = BinaryInteger + return nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-comment.go b/vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-comment.go new file mode 100644 index 0000000..4592f63 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-comment.go @@ -0,0 +1,13 @@ +package lexer + +func (lexer *Lexer) tokenizeComment() { + lexer.currentToken.Kind = Comment + lexer.currentToken.append('#') + for ; lexer.reader.HasNext(); lexer.reader.Next() { + char := lexer.reader.Char() + if char == '\n' { + break + } + lexer.currentToken.append(char) + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-float.go b/vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-float.go new file mode 100644 index 0000000..f93d10b --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-float.go @@ -0,0 +1,36 @@ +package lexer + +func (lexer *Lexer) tokenizeFloat() error { + if !lexer.reader.HasNext() { + lexer.reader.Redo() + lexer.currentToken.Contents = lexer.currentToken.Contents[:len(lexer.currentToken.Contents)-1] + lexer.currentToken.Kind = Literal + lexer.currentToken.DirectValue = Integer + return nil + } + nextDigit := lexer.reader.Char() + if !('0' <= nextDigit && nextDigit <= '9') { + lexer.reader.Redo() + lexer.currentToken.Contents = lexer.currentToken.Contents[:len(lexer.currentToken.Contents)-1] + lexer.currentToken.Kind = Literal + lexer.currentToken.DirectValue = Integer + return nil + } + lexer.reader.Next() + lexer.currentToken.append(nextDigit) + for ; lexer.reader.HasNext(); lexer.reader.Next() { + nextDigit = lexer.reader.Char() + if ('0' <= nextDigit && nextDigit <= '9') || nextDigit == '_' { + lexer.currentToken.append(nextDigit) + } else if (nextDigit == 'e') || (nextDigit == 'E') { + lexer.reader.Next() + lexer.currentToken.append(nextDigit) + return lexer.tokenizeScientificFloat() + } else { + break + } + } + lexer.currentToken.Kind = Literal + lexer.currentToken.DirectValue = Float + return nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-hex.go b/vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-hex.go new file mode 100644 index 0000000..56fab56 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-hex.go @@ -0,0 +1,38 @@ +package lexer + +import "errors" + +var ( + HexInvalidSyntax = errors.New("invalid hex integer syntax") +) + +func (lexer *Lexer) tokenizeHexadecimal() error { + if !lexer.reader.HasNext() { + lexer.currentToken.Kind = Literal + lexer.currentToken.DirectValue = InvalidDirectValue + return HexInvalidSyntax + } + nextDigit := lexer.reader.Char() + if !(('0' <= nextDigit && nextDigit <= '9') || + ('a' <= nextDigit && nextDigit <= 'f') || + ('A' <= nextDigit && nextDigit <= 'F')) { + lexer.currentToken.Kind = Literal + lexer.currentToken.DirectValue = InvalidDirectValue + return HexInvalidSyntax + } + lexer.reader.Next() + lexer.currentToken.append(nextDigit) + for ; lexer.reader.HasNext(); lexer.reader.Next() { + nextDigit = lexer.reader.Char() + if !(('0' <= nextDigit && nextDigit <= '9') || + ('a' <= nextDigit && nextDigit <= 'f') || + ('A' <= nextDigit && nextDigit <= 'F')) && + nextDigit != '_' { + break + } + lexer.currentToken.append(nextDigit) + } + lexer.currentToken.Kind = Literal + lexer.currentToken.DirectValue = HexadecimalInteger + return nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-interger.go b/vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-interger.go new file mode 100644 index 0000000..912a0d6 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-interger.go @@ -0,0 +1,48 @@ +package lexer + +func (lexer *Lexer) tokenizeInteger() error { + if !lexer.reader.HasNext() { + lexer.currentToken.Kind = Literal + lexer.currentToken.DirectValue = Integer + return nil + } + nextDigit := lexer.reader.Char() + switch nextDigit { + case '.': + lexer.reader.Next() + lexer.currentToken.append(nextDigit) + return lexer.tokenizeFloat() + case 'e', 'E': + lexer.reader.Next() + lexer.currentToken.append(nextDigit) + return lexer.tokenizeScientificFloat() + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + // If no of this match return + default: + lexer.currentToken.Kind = Literal + lexer.currentToken.DirectValue = Integer + return nil + } + lexer.reader.Next() + lexer.currentToken.append(nextDigit) +loop: + for ; lexer.reader.HasNext(); lexer.reader.Next() { + nextDigit = lexer.reader.Char() + switch nextDigit { + case 'e', 'E': + lexer.currentToken.append(nextDigit) + return lexer.tokenizeScientificFloat() + case '.': + lexer.reader.Next() + lexer.currentToken.append(nextDigit) + return lexer.tokenizeFloat() + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '_': + lexer.currentToken.append(nextDigit) + default: + break loop + } + } + lexer.currentToken.Kind = Literal + lexer.currentToken.DirectValue = Integer + return nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-numeric.go b/vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-numeric.go new file mode 100644 index 0000000..4d5374c --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-numeric.go @@ -0,0 +1,39 @@ +package lexer + +func (lexer *Lexer) tokenizeNumeric() error { + if !lexer.reader.HasNext() { + lexer.currentToken.Kind = Literal + lexer.currentToken.DirectValue = Integer + return nil + } + nextChar := lexer.reader.Char() + lexer.reader.Next() + if lexer.currentToken.Contents[0] == '0' { + switch nextChar { + case 'x', 'X': // Hexadecimal + lexer.currentToken.append(nextChar) + return lexer.tokenizeHexadecimal() + case 'b', 'B': // Binary + lexer.currentToken.append(nextChar) + return lexer.tokenizeBinary() + case 'o', 'O': // Octal + lexer.currentToken.append(nextChar) + return lexer.tokenizeOctal() + } + } + switch nextChar { + case 'e', 'E': // Scientific float + lexer.currentToken.append(nextChar) + return lexer.tokenizeScientificFloat() + case '.': // Maybe a float + lexer.currentToken.append(nextChar) + return lexer.tokenizeFloat() // Integer, Float Or Scientific Float + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '_': + lexer.currentToken.append(nextChar) + return lexer.tokenizeInteger() // Integer, Float or Scientific Float + } + lexer.reader.Redo() + lexer.currentToken.Kind = Literal + lexer.currentToken.DirectValue = Integer + return nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-octal.go b/vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-octal.go new file mode 100644 index 0000000..edad232 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-octal.go @@ -0,0 +1,33 @@ +package lexer + +import "errors" + +var ( + OctalInvalidSyntax = errors.New("invalid octal integer syntax") +) + +func (lexer *Lexer) tokenizeOctal() error { + if !lexer.reader.HasNext() { + lexer.currentToken.Kind = Literal + lexer.currentToken.DirectValue = InvalidDirectValue + return OctalInvalidSyntax + } + nextDigit := lexer.reader.Char() + if !('0' <= nextDigit && nextDigit <= '7') { + lexer.currentToken.Kind = Literal + lexer.currentToken.DirectValue = InvalidDirectValue + return OctalInvalidSyntax + } + lexer.reader.Next() + lexer.currentToken.append(nextDigit) + for ; lexer.reader.HasNext(); lexer.reader.Next() { + nextDigit = lexer.reader.Char() + if !('0' <= nextDigit && nextDigit <= '7') && nextDigit != '_' { + break + } + lexer.currentToken.append(nextDigit) + } + lexer.currentToken.Kind = Literal + lexer.currentToken.DirectValue = OctalInteger + return nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-repeatable-operator.go b/vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-repeatable-operator.go new file mode 100644 index 0000000..863195e --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-repeatable-operator.go @@ -0,0 +1,40 @@ +package lexer + +func (lexer *Lexer) tokenizeRepeatableOperator( + singleDirectValue DirectValue, singleKind Kind, + doubleDirectValue DirectValue, doubleKind Kind, + assignSingleDirectValue DirectValue, assignSingleKind Kind, + assignDoubleDirectValue DirectValue, assignDoubleKind Kind, +) { + lexer.currentToken.Kind = singleKind + lexer.currentToken.DirectValue = singleDirectValue + if !lexer.reader.HasNext() { + return + } + nextChar := lexer.reader.Char() + if nextChar == '=' { + lexer.currentToken.Kind = assignSingleKind + lexer.currentToken.append(nextChar) + lexer.reader.Next() + lexer.currentToken.DirectValue = assignSingleDirectValue + return + } + if nextChar != lexer.currentToken.Contents[0] { + return + } + lexer.currentToken.append(nextChar) + lexer.reader.Next() + lexer.currentToken.Kind = doubleKind + lexer.currentToken.DirectValue = doubleDirectValue + if !lexer.reader.HasNext() { + return + } + nextNextChar := lexer.reader.Char() + if nextNextChar != '=' { + return + } + lexer.currentToken.append(nextNextChar) + lexer.currentToken.Kind = assignDoubleKind + lexer.reader.Next() + lexer.currentToken.DirectValue = assignDoubleDirectValue +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-scientific-float.go b/vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-scientific-float.go new file mode 100644 index 0000000..cbb1813 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-scientific-float.go @@ -0,0 +1,47 @@ +package lexer + +import "errors" + +var ( + ScientificFloatInvalidSyntax = errors.New("invalid scientific float syntax") +) + +func (lexer *Lexer) tokenizeScientificFloat() error { + if !lexer.reader.HasNext() { + lexer.currentToken.Kind = Literal + lexer.currentToken.DirectValue = InvalidDirectValue + return ScientificFloatInvalidSyntax + } + direction := lexer.reader.Char() + if (direction != '-') && (direction != '+') { + lexer.currentToken.Kind = Literal + lexer.currentToken.DirectValue = InvalidDirectValue + return ScientificFloatInvalidSyntax + } + lexer.reader.Next() + // Ensure next is a number + if !lexer.reader.HasNext() { + lexer.currentToken.Kind = Literal + lexer.currentToken.DirectValue = InvalidDirectValue + return ScientificFloatInvalidSyntax + } + lexer.currentToken.append(direction) + nextDigit := lexer.reader.Char() + if !('0' <= nextDigit && nextDigit <= '9') { + lexer.currentToken.Kind = Literal + lexer.currentToken.DirectValue = InvalidDirectValue + return ScientificFloatInvalidSyntax + } + lexer.currentToken.append(nextDigit) + lexer.reader.Next() + for ; lexer.reader.HasNext(); lexer.reader.Next() { + nextDigit = lexer.reader.Char() + if !('0' <= nextDigit && nextDigit <= '9') && nextDigit != '_' { + break + } + lexer.currentToken.append(nextDigit) + } + lexer.currentToken.Kind = Literal + lexer.currentToken.DirectValue = ScientificFloat + return nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-single-operator.go b/vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-single-operator.go new file mode 100644 index 0000000..7654f69 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-single-operator.go @@ -0,0 +1,19 @@ +package lexer + +func (lexer *Lexer) tokenizeSingleOperator( + single DirectValue, singleKind Kind, + assign DirectValue, assignKind Kind) { + lexer.currentToken.Kind = singleKind + lexer.currentToken.DirectValue = single + if !lexer.reader.HasNext() { + return + } + nextChar := lexer.reader.Char() + if nextChar != '=' { + return + } + lexer.currentToken.Kind = assignKind + lexer.currentToken.DirectValue = assign + lexer.currentToken.append(nextChar) + lexer.reader.Next() +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-string.go b/vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-string.go new file mode 100644 index 0000000..681674e --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-string.go @@ -0,0 +1,49 @@ +package lexer + +import "errors" + +var ( + StringInvalidEscape = errors.New("invalid string escape sequence") + StringNeverClosed = errors.New("string never closed") +) + +func (lexer *Lexer) tokenizeStringLikeExpressions(stringOpener rune) error { + var target DirectValue + switch stringOpener { + case '\'': + target = SingleQuoteString + case '"': + target = DoubleQuoteString + case '`': + target = CommandOutput + } + var directValue = InvalidDirectValue + escaped := false + finish := false + for ; lexer.reader.HasNext() && !finish; lexer.reader.Next() { + char := lexer.reader.Char() + if escaped { + switch char { + case '\\', '\'', '"', '`', 'a', 'b', 'e', 'f', 'n', 'r', 't', '?', 'u', 'x': + escaped = false + default: + return StringInvalidEscape + } + } else { + switch char { + case stringOpener: + directValue = target + finish = true + case '\\': + escaped = true + } + } + lexer.currentToken.append(char) + } + if directValue != target { + return StringNeverClosed + } + lexer.currentToken.Kind = Literal + lexer.currentToken.DirectValue = directValue + return nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-word.go b/vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-word.go new file mode 100644 index 0000000..b70e2c9 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/lexer/tokenize-word.go @@ -0,0 +1,13 @@ +package lexer + +func (lexer *Lexer) tokenizeWord() { + for ; lexer.reader.HasNext(); lexer.reader.Next() { + char := lexer.reader.Char() + if ('a' <= char && char <= 'z') || ('A' <= char && char <= 'Z') || ('0' <= char && char <= '9') || (char == '_') { + lexer.currentToken.append(char) + } else { + break + } + } + lexer.currentToken.Kind, lexer.currentToken.DirectValue = lexer.detectKindAndDirectValue() +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/compiler/parser/ToDo.md b/vendor/github.com/shoriwe/gplasma/pkg/parser/ToDo.md similarity index 100% rename from vendor/github.com/shoriwe/gplasma/pkg/compiler/parser/ToDo.md rename to vendor/github.com/shoriwe/gplasma/pkg/parser/ToDo.md diff --git a/vendor/github.com/shoriwe/gplasma/pkg/parser/common.go b/vendor/github.com/shoriwe/gplasma/pkg/parser/common.go new file mode 100644 index 0000000..273532f --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/parser/common.go @@ -0,0 +1,36 @@ +package parser + +import ( + "github.com/shoriwe/gplasma/pkg/lexer" +) + +func (parser *Parser) removeNewLines() error { + for parser.matchDirectValue(lexer.NewLine) { + tokenizingError := parser.next() + if tokenizingError != nil { + return tokenizingError + } + } + return nil +} + +func (parser *Parser) matchDirectValue(directValue lexer.DirectValue) bool { + if parser.currentToken == nil { + return false + } + return parser.currentToken.DirectValue == directValue +} + +func (parser *Parser) matchKind(kind lexer.Kind) bool { + if parser.currentToken == nil { + return false + } + return parser.currentToken.Kind == kind +} + +func (parser *Parser) matchString(value string) bool { + if parser.currentToken == nil { + return false + } + return parser.currentToken.String() == value +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/parser/errors.go b/vendor/github.com/shoriwe/gplasma/pkg/parser/errors.go new file mode 100644 index 0000000..47262f1 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/parser/errors.go @@ -0,0 +1,47 @@ +package parser + +import ( + "errors" + "fmt" +) + +var ( + UnknownToken = errors.New("unknown token") + BeginRepeated = errors.New("repeated begin statement") + EndRepeated = errors.New("repeated end statement") +) + +func (parser *Parser) newError(message string) error { + if parser.lineStack.HasNext() { + return fmt.Errorf("SyntaxError: %s, at line %d", message, parser.lineStack.Peek()) + } + return fmt.Errorf("SyntaxError: %s", message) +} + +func (parser *Parser) newSyntaxError(nodeType string) error { + return parser.newError(fmt.Sprintf("invalid %s syntax", nodeType)) +} + +func (parser *Parser) expectingExpressionError(nodeType string) error { + return parser.newError(fmt.Sprintf("expecting expression but received %s", nodeType)) +} + +func (parser *Parser) expectingIdentifier(nodeType string) error { + return parser.newError(fmt.Sprintf("expecting identifier but received %s", nodeType)) +} + +func (parser *Parser) statementNeverEndedError(nodeType string) error { + return parser.newError(fmt.Sprintf("statement %s never ended", nodeType)) +} + +func (parser *Parser) invalidTokenKind() error { + return parser.newError(fmt.Sprintf("invalid token kind")) +} + +func (parser *Parser) expressionNeverClosedError(nodeType string) error { + return parser.newError(fmt.Sprintf("expression %s never closed", nodeType)) +} + +func (parser *Parser) expectingFunctionDefinition(nodeType string) error { + return parser.newError(fmt.Sprintf("expecting function definition but received %s", nodeType)) +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/compiler/parser/grammar.bnf b/vendor/github.com/shoriwe/gplasma/pkg/parser/grammar.bnf similarity index 100% rename from vendor/github.com/shoriwe/gplasma/pkg/compiler/parser/grammar.bnf rename to vendor/github.com/shoriwe/gplasma/pkg/parser/grammar.bnf diff --git a/vendor/github.com/shoriwe/gplasma/pkg/parser/iter.go b/vendor/github.com/shoriwe/gplasma/pkg/parser/iter.go new file mode 100644 index 0000000..004656e --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/parser/iter.go @@ -0,0 +1,21 @@ +package parser + +import ( + "github.com/shoriwe/gplasma/pkg/lexer" +) + +func (parser *Parser) hasNext() bool { + return !parser.complete +} + +func (parser *Parser) next() error { + token, tokenizingError := parser.lexer.Next() + if tokenizingError != nil { + return tokenizingError + } + if token.Kind == lexer.EOF { + parser.complete = true + } + parser.currentToken = token + return nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/parser/names.go b/vendor/github.com/shoriwe/gplasma/pkg/parser/names.go new file mode 100644 index 0000000..2a709d3 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/parser/names.go @@ -0,0 +1,43 @@ +package parser + +const ( + ForStatement = "For statement" + UntilStatement = "Until statement" + ModuleStatement = "Module statement" + FunctionDefinitionStatement = "Function Definition statement" + GeneratorDefinitionStatement = "Generator Definition statement" + ClassStatement = "Class statement" + ElseBlock = "Else Block" + BeginStatement = "Begin statement" + EndStatement = "End statement" + InterfaceStatement = "Interface statement" + BinaryExpression = "Binary expression" + PointerExpression = "Pointer expression" + LambdaExpression = "Lambda expression" + ParenthesesExpression = "Parentheses expression" + TupleExpression = "Tuple expression" + ArrayExpression = "Array expression" + HashExpression = "Hash expression" + WhileStatement = "While statement" + DoWhileStatement = "Do-While statement" + IfStatement = "If statement" + ElifBlock = "Elif Block" + UnlessStatement = "Unless statement" + SwitchStatement = "Switch statement" + CaseBlock = "Targets Block" + DefaultBlock = "Default Block" + ReturnStatement = "Return statement" + YieldStatement = "Yield statement" + SuperExpression = "Super expression" + DeleteStatement = "Delete expression" + DeferStatement = "Defer statement" + RequireStatement = "Require expression" + SelectorExpression = "Selector expression" + MethodInvocationExpression = "Method Invocation expression" + IndexExpression = "Index expression" + IfOneLinerExpression = "If One Liner expression" + UnlessOneLinerExpression = "Unless One Liner expression" + OneLineElseBlock = "One Line Else Block" + GeneratorExpression = "Generator expression" + AssignStatement = "Assign statement" +) diff --git a/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-array-expression.go b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-array-expression.go new file mode 100644 index 0000000..82fe425 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-array-expression.go @@ -0,0 +1,55 @@ +package parser + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/lexer" +) + +func (parser *Parser) parseArrayExpression() (*ast.ArrayExpression, error) { + tokenizingError := parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + newLinesRemoveError := parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + var values []ast.Expression + for parser.hasNext() { + if parser.matchDirectValue(lexer.CloseSquareBracket) { + break + } + newLinesRemoveError = parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + + value, parsingError := parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + if _, ok := value.(ast.Expression); !ok { + return nil, parser.expectingExpressionError(ArrayExpression) + } + values = append(values, value.(ast.Expression)) + newLinesRemoveError = parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + if parser.matchDirectValue(lexer.Comma) { + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + } else if !parser.matchDirectValue(lexer.CloseSquareBracket) { + return nil, parser.newSyntaxError(ArrayExpression) + } + } + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + return &ast.ArrayExpression{ + Values: values, + }, nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-assignment-statement.go b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-assignment-statement.go new file mode 100644 index 0000000..929cf72 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-assignment-statement.go @@ -0,0 +1,30 @@ +package parser + +import ( + "github.com/shoriwe/gplasma/pkg/ast" +) + +func (parser *Parser) parseAssignmentStatement(leftHandSide ast.Expression) (*ast.AssignStatement, error) { + assignmentToken := parser.currentToken + tokenizingError := parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + newLinesRemoveError := parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + + rightHandSide, parsingError := parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + if _, ok := rightHandSide.(ast.Expression); !ok { + return nil, parser.expectingExpressionError(AssignStatement) + } + return &ast.AssignStatement{ + LeftHandSide: leftHandSide, + AssignOperator: assignmentToken, + RightHandSide: rightHandSide.(ast.Expression), + }, nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-begin-statement.go b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-begin-statement.go new file mode 100644 index 0000000..e5b734d --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-begin-statement.go @@ -0,0 +1,46 @@ +package parser + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/lexer" +) + +func (parser *Parser) parseBeginStatement() (*ast.BeginStatement, error) { + tokenizingError := parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + if !parser.matchDirectValue(lexer.NewLine) { + return nil, parser.newSyntaxError(BeginStatement) + } + var body []ast.Node + var bodyNode ast.Node + var parsingError error + for parser.hasNext() { + if parser.matchKind(lexer.Separator) { + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + if parser.matchDirectValue(lexer.End) { + break + } + continue + } + bodyNode, parsingError = parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + body = append(body, bodyNode) + } + if !parser.matchDirectValue(lexer.End) { + return nil, parser.statementNeverEndedError(BeginStatement) + } + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + return &ast.BeginStatement{ + Body: body, + }, nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-binary-expression.go b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-binary-expression.go new file mode 100644 index 0000000..07fffbc --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-binary-expression.go @@ -0,0 +1,53 @@ +package parser + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/lexer" +) + +func (parser *Parser) parseBinaryExpression(precedence lexer.DirectValue) (ast.Node, error) { + var leftHandSide ast.Node + var rightHandSide ast.Node + var parsingError error + leftHandSide, parsingError = parser.parseUnaryExpression() + if parsingError != nil { + return nil, parsingError + } + if _, ok := leftHandSide.(ast.Statement); ok { + return leftHandSide, nil + } + for parser.hasNext() { + if !parser.matchKind(lexer.Operator) && + !parser.matchKind(lexer.Comparator) { + break + } + newLinesRemoveError := parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + operator := parser.currentToken + operatorPrecedence := parser.currentToken.DirectValue + if operatorPrecedence < precedence { + return leftHandSide, nil + } + tokenizingError := parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + + rightHandSide, parsingError = parser.parseBinaryExpression(operatorPrecedence + 1) + if parsingError != nil { + return nil, parsingError + } + if _, ok := rightHandSide.(ast.Expression); !ok { + return nil, parser.expectingExpressionError(BinaryExpression) + } + + leftHandSide = &ast.BinaryExpression{ + LeftHandSide: leftHandSide.(ast.Expression), + Operator: operator, + RightHandSide: rightHandSide.(ast.Expression), + } + } + return leftHandSide, nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-break-statement.go b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-break-statement.go new file mode 100644 index 0000000..30a99f9 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-break-statement.go @@ -0,0 +1,13 @@ +package parser + +import ( + "github.com/shoriwe/gplasma/pkg/ast" +) + +func (parser *Parser) parseBreakStatement() (*ast.BreakStatement, error) { + tokenizingError := parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + return &ast.BreakStatement{}, nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-class-statement.go b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-class-statement.go new file mode 100644 index 0000000..a5b9363 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-class-statement.go @@ -0,0 +1,105 @@ +package parser + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/lexer" +) + +func (parser *Parser) parseClassStatement() (*ast.ClassStatement, error) { + tokenizingError := parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + newLinesRemoveError := parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + if !parser.matchKind(lexer.IdentifierKind) { + return nil, parser.newSyntaxError(ClassStatement) + } + name := &ast.Identifier{ + Token: parser.currentToken, + } + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + var bases []ast.Expression + var base ast.Node + var parsingError error + if parser.matchDirectValue(lexer.OpenParentheses) { + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + for parser.hasNext() { + newLinesRemoveError = parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + base, parsingError = parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + if _, ok := base.(ast.Expression); !ok { + return nil, parser.expectingExpressionError(ClassStatement) + } + bases = append(bases, base.(ast.Expression)) + newLinesRemoveError = parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + if parser.matchDirectValue(lexer.Comma) { + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + } else if parser.matchDirectValue(lexer.CloseParentheses) { + break + } else { + return nil, parser.newSyntaxError(ClassStatement) + } + } + if !parser.matchDirectValue(lexer.CloseParentheses) { + return nil, parser.newSyntaxError(ClassStatement) + } + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + } + if !parser.matchDirectValue(lexer.NewLine) { + return nil, parser.newSyntaxError(ClassStatement) + } + var body []ast.Node + var bodyNode ast.Node + for parser.hasNext() { + if parser.matchKind(lexer.Separator) { + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + if parser.matchDirectValue(lexer.End) { + break + } + continue + } + bodyNode, parsingError = parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + body = append(body, bodyNode) + } + if !parser.matchDirectValue(lexer.End) { + return nil, parser.statementNeverEndedError(ClassStatement) + } + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + return &ast.ClassStatement{ + Name: name, + Bases: bases, + Body: body, + }, nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-continue-statement.go b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-continue-statement.go new file mode 100644 index 0000000..cbeb62a --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-continue-statement.go @@ -0,0 +1,13 @@ +package parser + +import ( + "github.com/shoriwe/gplasma/pkg/ast" +) + +func (parser *Parser) parseContinueStatement() (*ast.ContinueStatement, error) { + tokenizingError := parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + return &ast.ContinueStatement{}, nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-defer-statement.go b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-defer-statement.go new file mode 100644 index 0000000..9f84e37 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-defer-statement.go @@ -0,0 +1,20 @@ +package parser + +import "github.com/shoriwe/gplasma/pkg/ast" + +func (parser *Parser) parseDeferStatement() (*ast.DeferStatement, error) { + tokenizingError := parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + x, parsingError := parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + if _, ok := x.(*ast.MethodInvocationExpression); !ok { + return nil, parser.expectingExpressionError(DeferStatement) + } + return &ast.DeferStatement{ + X: x.(*ast.MethodInvocationExpression), + }, nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-delete-statement.go b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-delete-statement.go new file mode 100644 index 0000000..d8b9f9b --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-delete-statement.go @@ -0,0 +1,20 @@ +package parser + +import "github.com/shoriwe/gplasma/pkg/ast" + +func (parser *Parser) parseDeleteStatement() (*ast.DeleteStatement, error) { + tokenizingError := parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + x, parsingError := parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + if _, ok := x.(ast.Expression); !ok { + return nil, parser.expectingExpressionError(DeleteStatement) + } + return &ast.DeleteStatement{ + X: x.(ast.Expression), + }, nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-do-while.go b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-do-while.go new file mode 100644 index 0000000..4369ed6 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-do-while.go @@ -0,0 +1,62 @@ +package parser + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/lexer" +) + +func (parser *Parser) parseDoWhileStatement() (*ast.DoWhileStatement, error) { + tokenizingError := parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + var body []ast.Node + var bodyNode ast.Node + var parsingError error + if !parser.matchDirectValue(lexer.NewLine) { + return nil, parser.newSyntaxError(DoWhileStatement) + } + // Parse Body + for parser.hasNext() { + if parser.matchKind(lexer.Separator) { + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + if parser.matchDirectValue(lexer.While) { + break + } + continue + } + bodyNode, parsingError = parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + body = append(body, bodyNode) + } + // Parse Condition + if !parser.matchDirectValue(lexer.While) { + return nil, parser.newSyntaxError(DoWhileStatement) + } + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + newLinesRemoveError := parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + + var condition ast.Node + condition, parsingError = parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + if _, ok := condition.(ast.Expression); !ok { + return nil, parser.expectingExpressionError(WhileStatement) + } + return &ast.DoWhileStatement{ + Condition: condition.(ast.Expression), + Body: body, + }, nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-end-statement.go b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-end-statement.go new file mode 100644 index 0000000..8d65070 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-end-statement.go @@ -0,0 +1,46 @@ +package parser + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/lexer" +) + +func (parser *Parser) parseEndStatement() (*ast.EndStatement, error) { + tokenizingError := parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + if !parser.matchDirectValue(lexer.NewLine) { + return nil, parser.newSyntaxError(EndStatement) + } + var body []ast.Node + var bodyNode ast.Node + var parsingError error + for parser.hasNext() { + if parser.matchKind(lexer.Separator) { + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + if parser.matchDirectValue(lexer.End) { + break + } + continue + } + bodyNode, parsingError = parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + body = append(body, bodyNode) + } + if !parser.matchDirectValue(lexer.End) { + return nil, parser.statementNeverEndedError(EndStatement) + } + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + return &ast.EndStatement{ + Body: body, + }, nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-for-statement.go b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-for-statement.go new file mode 100644 index 0000000..1d973c3 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-for-statement.go @@ -0,0 +1,110 @@ +package parser + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/lexer" +) + +func (parser *Parser) parseForStatement() (*ast.ForLoopStatement, error) { + tokenizingError := parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + newLinesRemoveError := parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + var receivers []*ast.Identifier + for parser.hasNext() { + if parser.matchDirectValue(lexer.In) { + break + } else if !parser.matchKind(lexer.IdentifierKind) { + return nil, parser.newSyntaxError(ForStatement) + } + newLinesRemoveError = parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + receivers = append(receivers, &ast.Identifier{ + Token: parser.currentToken, + }) + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + newLinesRemoveError = parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + if parser.matchDirectValue(lexer.Comma) { + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + } else if parser.matchDirectValue(lexer.In) { + break + } else { + return nil, parser.newSyntaxError(ForStatement) + } + } + newLinesRemoveError = parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + if !parser.matchDirectValue(lexer.In) { + return nil, parser.newSyntaxError(ForStatement) + } + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + newLinesRemoveError = parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + source, parsingError := parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + if _, ok := source.(ast.Expression); !ok { + return nil, parser.expectingExpressionError(ForStatement) + } + if !parser.matchDirectValue(lexer.NewLine) { + return nil, parser.newSyntaxError(ForStatement) + } + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + var body []ast.Node + var bodyNode ast.Node + for parser.hasNext() { + if parser.matchKind(lexer.Separator) { + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + if parser.matchDirectValue(lexer.End) { + break + } + continue + } + bodyNode, parsingError = parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + body = append(body, bodyNode) + } + if !parser.matchDirectValue(lexer.End) { + return nil, parser.statementNeverEndedError(ForStatement) + } + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + return &ast.ForLoopStatement{ + Receivers: receivers, + Source: source.(ast.Expression), + Body: body, + }, nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-function-definition-statement.go b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-function-definition-statement.go new file mode 100644 index 0000000..483e4b8 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-function-definition-statement.go @@ -0,0 +1,126 @@ +package parser + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/lexer" +) + +func (parser *Parser) parseFunctionDefinitionStatement() (*ast.FunctionDefinitionStatement, error) { + tokenizingError := parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + newLinesRemoveError := parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + if !parser.matchKind(lexer.IdentifierKind) { + return nil, parser.newSyntaxError(FunctionDefinitionStatement) + } + name := &ast.Identifier{ + Token: parser.currentToken, + } + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + newLinesRemoveError = parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + if !parser.matchDirectValue(lexer.OpenParentheses) { + return nil, parser.newSyntaxError(FunctionDefinitionStatement) + } + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + var arguments []*ast.Identifier + for parser.hasNext() { + if parser.matchDirectValue(lexer.CloseParentheses) { + break + } + newLinesRemoveError = parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + if !parser.matchKind(lexer.IdentifierKind) { + return nil, parser.newSyntaxError(FunctionDefinitionStatement) + } + argument := &ast.Identifier{ + Token: parser.currentToken, + } + arguments = append(arguments, argument) + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + newLinesRemoveError = parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + if parser.matchDirectValue(lexer.Comma) { + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + } else if parser.matchDirectValue(lexer.CloseParentheses) { + break + } else { + return nil, parser.newSyntaxError(FunctionDefinitionStatement) + } + } + if !parser.matchDirectValue(lexer.CloseParentheses) { + return nil, parser.newSyntaxError(FunctionDefinitionStatement) + } + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + if !parser.matchDirectValue(lexer.NewLine) { + return nil, parser.newSyntaxError(FunctionDefinitionStatement) + } + var body []ast.Node + var bodyNode ast.Node + var parsingError error + for parser.hasNext() { + if parser.matchKind(lexer.Separator) { + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + if parser.matchDirectValue(lexer.End) { + break + } + continue + } + bodyNode, parsingError = parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + body = append(body, bodyNode) + } + if !parser.matchDirectValue(lexer.End) { + return nil, parser.statementNeverEndedError(FunctionDefinitionStatement) + } + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + body = append(body, &ast.ReturnStatement{ + Results: []ast.Expression{&ast.BasicLiteralExpression{ + Token: &lexer.Token{ + Contents: []rune(lexer.NoneString), + DirectValue: lexer.None, + Kind: lexer.NoneType, + }, + Kind: lexer.NoneType, + DirectValue: lexer.None, + }}, + }) + return &ast.FunctionDefinitionStatement{ + Name: name, + Arguments: arguments, + Body: body, + }, nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-generator-expression.go b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-generator-expression.go new file mode 100644 index 0000000..cd94576 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-generator-expression.go @@ -0,0 +1,88 @@ +package parser + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/lexer" +) + +func (parser *Parser) parseGeneratorExpression(operation ast.Expression) (*ast.GeneratorExpression, error) { + tokenizingError := parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + newLinesRemoveError := parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + var variables []*ast.Identifier + numberOfVariables := 0 + for parser.hasNext() { + if parser.matchDirectValue(lexer.In) { + break + } + newLinesRemoveError = parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + if !parser.matchKind(lexer.IdentifierKind) { + return nil, parser.newSyntaxError(GeneratorExpression) + } + variables = append(variables, &ast.Identifier{ + Token: parser.currentToken, + }) + numberOfVariables++ + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + newLinesRemoveError = parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + if parser.matchDirectValue(lexer.Comma) { + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + } + } + if numberOfVariables == 0 { + return nil, parser.newSyntaxError(GeneratorExpression) + } + if !parser.matchDirectValue(lexer.In) { + return nil, parser.newSyntaxError(GeneratorExpression) + } + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + newLinesRemoveError = parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + + source, parsingError := parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + if _, ok := source.(ast.Expression); !ok { + return nil, parser.expectingExpressionError(GeneratorExpression) + } + newLinesRemoveError = parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + // Finally detect the closing parentheses + if !parser.matchDirectValue(lexer.CloseParentheses) { + return nil, parser.newSyntaxError(GeneratorExpression) + } + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + return &ast.GeneratorExpression{ + Operation: operation, + Receivers: variables, + Source: source.(ast.Expression), + }, nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-generator-statement.go b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-generator-statement.go new file mode 100644 index 0000000..951abd7 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-generator-statement.go @@ -0,0 +1,126 @@ +package parser + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/lexer" +) + +func (parser *Parser) parseGeneratorDefinitionStatement() (*ast.GeneratorDefinitionStatement, error) { + tokenizingError := parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + newLinesRemoveError := parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + if !parser.matchKind(lexer.IdentifierKind) { + return nil, parser.newSyntaxError(GeneratorDefinitionStatement) + } + name := &ast.Identifier{ + Token: parser.currentToken, + } + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + newLinesRemoveError = parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + if !parser.matchDirectValue(lexer.OpenParentheses) { + return nil, parser.newSyntaxError(GeneratorDefinitionStatement) + } + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + var arguments []*ast.Identifier + for parser.hasNext() { + if parser.matchDirectValue(lexer.CloseParentheses) { + break + } + newLinesRemoveError = parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + if !parser.matchKind(lexer.IdentifierKind) { + return nil, parser.newSyntaxError(GeneratorDefinitionStatement) + } + argument := &ast.Identifier{ + Token: parser.currentToken, + } + arguments = append(arguments, argument) + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + newLinesRemoveError = parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + if parser.matchDirectValue(lexer.Comma) { + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + } else if parser.matchDirectValue(lexer.CloseParentheses) { + break + } else { + return nil, parser.newSyntaxError(GeneratorDefinitionStatement) + } + } + if !parser.matchDirectValue(lexer.CloseParentheses) { + return nil, parser.newSyntaxError(GeneratorDefinitionStatement) + } + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + if !parser.matchDirectValue(lexer.NewLine) { + return nil, parser.newSyntaxError(GeneratorDefinitionStatement) + } + var body []ast.Node + var bodyNode ast.Node + var parsingError error + for parser.hasNext() { + if parser.matchKind(lexer.Separator) { + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + if parser.matchDirectValue(lexer.End) { + break + } + continue + } + bodyNode, parsingError = parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + body = append(body, bodyNode) + } + if !parser.matchDirectValue(lexer.End) { + return nil, parser.statementNeverEndedError(GeneratorDefinitionStatement) + } + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + body = append(body, &ast.ReturnStatement{ + Results: []ast.Expression{&ast.BasicLiteralExpression{ + Token: &lexer.Token{ + Contents: []rune(lexer.NoneString), + DirectValue: lexer.None, + Kind: lexer.NoneType, + }, + Kind: lexer.NoneType, + DirectValue: lexer.None, + }}, + }) + return &ast.GeneratorDefinitionStatement{ + Name: name, + Arguments: arguments, + Body: body, + }, nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-hash-expression.go b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-hash-expression.go new file mode 100644 index 0000000..186c36a --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-hash-expression.go @@ -0,0 +1,86 @@ +package parser + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/lexer" +) + +func (parser *Parser) parseHashExpression() (*ast.HashExpression, error) { + tokenizingError := parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + newLinesRemoveError := parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + var values []*ast.KeyValue + var leftHandSide ast.Node + var rightHandSide ast.Node + var parsingError error + for parser.hasNext() { + if parser.matchDirectValue(lexer.CloseBrace) { + break + } + newLinesRemoveError = parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + + leftHandSide, parsingError = parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + if _, ok := leftHandSide.(ast.Expression); !ok { + return nil, parser.expectingExpressionError(HashExpression) + } + newLinesRemoveError = parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + if !parser.matchDirectValue(lexer.Colon) { + return nil, parser.newSyntaxError(HashExpression) + } + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + newLinesRemoveError = parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + + rightHandSide, parsingError = parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + if _, ok := rightHandSide.(ast.Expression); !ok { + return nil, parser.expectingExpressionError(HashExpression) + } + values = append(values, &ast.KeyValue{ + Key: leftHandSide.(ast.Expression), + Value: rightHandSide.(ast.Expression), + }) + newLinesRemoveError = parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + if parser.matchDirectValue(lexer.Comma) { + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + } + newLinesRemoveError = parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + } + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + return &ast.HashExpression{ + Values: values, + }, nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-if-one-liner-expression.go b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-if-one-liner-expression.go new file mode 100644 index 0000000..98b81b3 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-if-one-liner-expression.go @@ -0,0 +1,53 @@ +package parser + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/lexer" +) + +func (parser *Parser) parseIfOneLinerExpression(result ast.Expression) (*ast.IfOneLinerExpression, error) { + tokenizingError := parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + newLinesRemoveError := parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + + condition, parsingError := parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + if _, ok := condition.(ast.Expression); !ok { + return nil, parser.expectingExpressionError(IfOneLinerExpression) + } + if !parser.matchDirectValue(lexer.Else) { + return &ast.IfOneLinerExpression{ + Result: result, + Condition: condition.(ast.Expression), + ElseResult: nil, + }, nil + } + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + newLinesRemoveError = parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + var elseResult ast.Node + elseResult, parsingError = parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + if _, ok := elseResult.(ast.Expression); !ok { + return nil, parser.expectingExpressionError(OneLineElseBlock) + } + return &ast.IfOneLinerExpression{ + Result: result, + Condition: condition.(ast.Expression), + ElseResult: elseResult.(ast.Expression), + }, nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-if-statement.go b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-if-statement.go new file mode 100644 index 0000000..cc7b1e5 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-if-statement.go @@ -0,0 +1,141 @@ +package parser + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/lexer" +) + +func (parser *Parser) parseIfStatement() (*ast.IfStatement, error) { + tokenizingError := parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + newLinesRemoveError := parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + + condition, parsingError := parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + if _, ok := condition.(ast.Expression); !ok { + return nil, parser.expectingExpressionError(IfStatement) + } + if !parser.matchDirectValue(lexer.NewLine) { + return nil, parser.newSyntaxError(IfStatement) + } + // Parse If + root := &ast.IfStatement{ + Condition: condition.(ast.Expression), + Body: []ast.Node{}, + Else: []ast.Node{}, + } + var bodyNode ast.Node + for parser.hasNext() { + if parser.matchKind(lexer.Separator) { + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + if parser.matchDirectValue(lexer.Elif) || + parser.matchDirectValue(lexer.Else) || + parser.matchDirectValue(lexer.End) { + break + } + continue + } + bodyNode, parsingError = parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + root.Body = append(root.Body, bodyNode) + } + // Parse Elifs + lastCondition := root + if parser.matchDirectValue(lexer.Elif) { + elifBlocksParsingLoop: + for parser.hasNext() { + block := ast.ElifBlock{ + Condition: nil, + Body: nil, + } + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + condition, parsingError = parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + if _, ok := condition.(ast.Expression); !ok { + return nil, parser.expectingExpressionError(ElifBlock) + } + block.Condition = condition.(ast.Expression) + if !parser.matchDirectValue(lexer.NewLine) { + return nil, parser.newSyntaxError(IfStatement) + } + for parser.hasNext() { + if parser.matchKind(lexer.Separator) { + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + if parser.matchDirectValue(lexer.Else) || + parser.matchDirectValue(lexer.End) { + root.ElifBlocks = append(root.ElifBlocks, block) + break elifBlocksParsingLoop + } else if parser.matchDirectValue(lexer.Elif) { + break + } + continue + } + bodyNode, parsingError = parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + block.Body = append(block.Body, bodyNode) + } + if !parser.matchDirectValue(lexer.Elif) { + return nil, parser.newSyntaxError(ElifBlock) + } + root.ElifBlocks = append(root.ElifBlocks, block) + } + } + // Parse Default + if parser.matchDirectValue(lexer.Else) { + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + var elseBodyNode ast.Node + if !parser.matchDirectValue(lexer.NewLine) { + return nil, parser.newSyntaxError(ElseBlock) + } + for parser.hasNext() { + if parser.matchKind(lexer.Separator) { + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + if parser.matchDirectValue(lexer.End) { + break + } + continue + } + elseBodyNode, parsingError = parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + lastCondition.Else = append(lastCondition.Else, elseBodyNode) + } + } + if !parser.matchDirectValue(lexer.End) { + return nil, parser.statementNeverEndedError(IfStatement) + } + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + return root, nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-index-expression.go b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-index-expression.go new file mode 100644 index 0000000..682b905 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-index-expression.go @@ -0,0 +1,41 @@ +package parser + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/lexer" +) + +func (parser *Parser) parseIndexExpression(expression ast.Expression) (*ast.IndexExpression, error) { + tokenizationError := parser.next() + if tokenizationError != nil { + return nil, tokenizationError + } + newLinesRemoveError := parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + // var rightIndex ast.Node + + index, parsingError := parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + if _, ok := index.(ast.Expression); !ok { + return nil, parser.expectingExpressionError(IndexExpression) + } + newLinesRemoveError = parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + if !parser.matchDirectValue(lexer.CloseSquareBracket) { + return nil, parser.newSyntaxError(IndexExpression) + } + tokenizationError = parser.next() + if tokenizationError != nil { + return nil, tokenizationError + } + return &ast.IndexExpression{ + Source: expression, + Index: index.(ast.Expression), + }, nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-interface-statement.go b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-interface-statement.go new file mode 100644 index 0000000..ca080b0 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-interface-statement.go @@ -0,0 +1,116 @@ +package parser + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/lexer" +) + +func (parser *Parser) parseInterfaceStatement() (*ast.InterfaceStatement, error) { + tokenizingError := parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + newLinesRemoveError := parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + if !parser.matchKind(lexer.IdentifierKind) { + return nil, parser.newSyntaxError(InterfaceStatement) + } + name := &ast.Identifier{ + Token: parser.currentToken, + } + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + var bases []ast.Expression + var base ast.Node + var parsingError error + if parser.matchDirectValue(lexer.OpenParentheses) { + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + for parser.hasNext() { + newLinesRemoveError = parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + base, parsingError = parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + if _, ok := base.(ast.Expression); !ok { + return nil, parser.newSyntaxError(InterfaceStatement) + } + bases = append(bases, base.(ast.Expression)) + newLinesRemoveError = parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + if parser.matchDirectValue(lexer.Comma) { + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + } else if parser.matchDirectValue(lexer.CloseParentheses) { + break + } else { + return nil, parser.newSyntaxError(InterfaceStatement) + } + } + newLinesRemoveError = parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + if !parser.matchDirectValue(lexer.CloseParentheses) { + return nil, parser.newSyntaxError(InterfaceStatement) + } + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + } + if !parser.matchDirectValue(lexer.NewLine) { + return nil, parser.newSyntaxError(InterfaceStatement) + } + var methods []*ast.FunctionDefinitionStatement + var node ast.Node + for parser.hasNext() { + if parser.matchKind(lexer.Separator) { + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + if parser.matchDirectValue(lexer.End) { + break + } + continue + } + node, parsingError = parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + if _, ok := node.(*ast.FunctionDefinitionStatement); !ok { + return nil, parser.expectingFunctionDefinition(InterfaceStatement) + } + methods = append(methods, node.(*ast.FunctionDefinitionStatement)) + } + newLinesRemoveError = parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + if !parser.matchDirectValue(lexer.End) { + return nil, parser.statementNeverEndedError(InterfaceStatement) + } + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + return &ast.InterfaceStatement{ + Name: name, + Bases: bases, + MethodDefinitions: methods, + }, nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-lambda-expression.go b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-lambda-expression.go new file mode 100644 index 0000000..5f682d9 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-lambda-expression.go @@ -0,0 +1,71 @@ +package parser + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/lexer" +) + +func (parser *Parser) parseLambdaExpression() (*ast.LambdaExpression, error) { + var arguments []*ast.Identifier + tokenizingError := parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + for parser.hasNext() { + if parser.matchDirectValue(lexer.Colon) { + break + } + newLinesRemoveError := parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + + identifier, parsingError := parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + if _, ok := identifier.(*ast.Identifier); !ok { + return nil, parser.expectingIdentifier(LambdaExpression) + } + arguments = append(arguments, identifier.(*ast.Identifier)) + newLinesRemoveError = parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + if parser.matchDirectValue(lexer.Comma) { + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + } else if !parser.matchDirectValue(lexer.Colon) { + return nil, parser.newSyntaxError(LambdaExpression) + } + } + newLinesRemoveError := parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + if !parser.matchDirectValue(lexer.Colon) { + return nil, parser.newSyntaxError(LambdaExpression) + } + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + newLinesRemoveError = parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + + code, parsingError := parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + if _, ok := code.(ast.Expression); !ok { + return nil, parser.expectingExpressionError(LambdaExpression) + } + return &ast.LambdaExpression{ + Arguments: arguments, + Code: code.(ast.Expression), + }, nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-literal-expression.go b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-literal-expression.go new file mode 100644 index 0000000..2cc15a4 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-literal-expression.go @@ -0,0 +1,32 @@ +package parser + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/lexer" +) + +func (parser *Parser) parseLiteral() (ast.Expression, error) { + if !parser.matchKind(lexer.Literal) && + !parser.matchKind(lexer.Boolean) && + !parser.matchKind(lexer.NoneType) { + return nil, parser.invalidTokenKind() + } + + switch parser.currentToken.DirectValue { + case lexer.SingleQuoteString, lexer.DoubleQuoteString, lexer.ByteString, + lexer.Integer, lexer.HexadecimalInteger, lexer.BinaryInteger, lexer.OctalInteger, + lexer.Float, lexer.ScientificFloat, + lexer.True, lexer.False, lexer.None: + currentToken := parser.currentToken + tokenizingError := parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + return &ast.BasicLiteralExpression{ + Token: currentToken, + Kind: currentToken.Kind, + DirectValue: currentToken.DirectValue, + }, nil + } + return nil, parser.invalidTokenKind() +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-method-invocation-expression.go b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-method-invocation-expression.go new file mode 100644 index 0000000..ac623c2 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-method-invocation-expression.go @@ -0,0 +1,55 @@ +package parser + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/lexer" +) + +func (parser *Parser) parseMethodInvocationExpression(expression ast.Expression) (*ast.MethodInvocationExpression, error) { + var arguments []ast.Expression + // The first token is open parentheses + tokenizingError := parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + newLinesRemoveError := parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + for parser.hasNext() { + if parser.matchDirectValue(lexer.CloseParentheses) { + break + } + newLinesRemoveError = parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + + argument, parsingError := parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + if _, ok := argument.(ast.Expression); !ok { + return nil, parser.expectingExpressionError(MethodInvocationExpression) + } + arguments = append(arguments, argument.(ast.Expression)) + newLinesRemoveError = parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + if parser.matchDirectValue(lexer.Comma) { + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + } + } + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + return &ast.MethodInvocationExpression{ + Function: expression, + Arguments: arguments, + }, nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-module-statement.go b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-module-statement.go new file mode 100644 index 0000000..b1fe2d0 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-module-statement.go @@ -0,0 +1,61 @@ +package parser + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/lexer" +) + +func (parser *Parser) parseModuleStatement() (*ast.ModuleStatement, error) { + tokenizingError := parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + newLinesRemoveError := parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + if !parser.matchKind(lexer.IdentifierKind) { + return nil, parser.newSyntaxError(ModuleStatement) + } + name := &ast.Identifier{ + Token: parser.currentToken, + } + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + if !parser.matchDirectValue(lexer.NewLine) { + return nil, parser.newSyntaxError(ModuleStatement) + } + var body []ast.Node + var bodyNode ast.Node + var parsingError error + for parser.hasNext() { + if parser.matchKind(lexer.Separator) { + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + if parser.matchDirectValue(lexer.End) { + break + } + continue + } + bodyNode, parsingError = parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + body = append(body, bodyNode) + } + if !parser.matchDirectValue(lexer.End) { + return nil, parser.statementNeverEndedError(ModuleStatement) + } + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + return &ast.ModuleStatement{ + Name: name, + Body: body, + }, nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-operand.go b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-operand.go new file mode 100644 index 0000000..3f350e8 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-operand.go @@ -0,0 +1,77 @@ +package parser + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/lexer" +) + +func (parser *Parser) parseOperand() (ast.Node, error) { + switch parser.currentToken.Kind { + case lexer.Literal, lexer.Boolean, lexer.NoneType: + return parser.parseLiteral() + case lexer.IdentifierKind: + identifier := parser.currentToken + tokenizingError := parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + return &ast.Identifier{ + Token: identifier, + }, nil + case lexer.Keyword: + switch parser.currentToken.DirectValue { + case lexer.Lambda: + return parser.parseLambdaExpression() + case lexer.Super: + return parser.parseSuperExpression() + case lexer.Delete: + return parser.parseDeleteStatement() + case lexer.Defer: + return parser.parseDeferStatement() + case lexer.While: + return parser.parseWhileStatement() + case lexer.For: + return parser.parseForStatement() + case lexer.Until: + return parser.parseUntilStatement() + case lexer.If: + return parser.parseIfStatement() + case lexer.Unless: + return parser.parseUnlessStatement() + case lexer.Switch: + return parser.parseSwitchStatement() + case lexer.Module: + return parser.parseModuleStatement() + case lexer.Def: + return parser.parseFunctionDefinitionStatement() + case lexer.Generator: + return parser.parseGeneratorDefinitionStatement() + case lexer.Interface: + return parser.parseInterfaceStatement() + case lexer.Class: + return parser.parseClassStatement() + case lexer.Return: + return parser.parseReturnStatement() + case lexer.Yield: + return parser.parseYieldStatement() + case lexer.Continue: + return parser.parseContinueStatement() + case lexer.Break: + return parser.parseBreakStatement() + case lexer.Pass: + return parser.parsePassStatement() + case lexer.Do: + return parser.parseDoWhileStatement() + } + case lexer.Punctuation: + switch parser.currentToken.DirectValue { + case lexer.OpenParentheses: + return parser.parseParentheses() + case lexer.OpenSquareBracket: // Parse Arrays + return parser.parseArrayExpression() + case lexer.OpenBrace: // Parse Dictionaries + return parser.parseHashExpression() + } + } + return nil, UnknownToken +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-parentheses-expression.go b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-parentheses-expression.go new file mode 100644 index 0000000..cd5eb3a --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-parentheses-expression.go @@ -0,0 +1,101 @@ +package parser + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/lexer" +) + +func (parser *Parser) parseParentheses() (ast.Expression, error) { + /* + This should also parse generators + */ + tokenizingError := parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + newLinesRemoveError := parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + if parser.matchDirectValue(lexer.CloseParentheses) { + return nil, parser.newSyntaxError(ParenthesesExpression) + } + + firstExpression, parsingError := parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + if _, ok := firstExpression.(ast.Expression); !ok { + return nil, parser.expectingExpressionError(ParenthesesExpression) + } + newLinesRemoveError = parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + if parser.matchDirectValue(lexer.For) { + return parser.parseGeneratorExpression(firstExpression.(ast.Expression)) + } + if parser.matchDirectValue(lexer.CloseParentheses) { + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + return &ast.ParenthesesExpression{ + X: firstExpression.(ast.Expression), + }, nil + } + if !parser.matchDirectValue(lexer.Comma) { + return nil, parser.newSyntaxError(ParenthesesExpression) + } + var values []ast.Expression + values = append(values, firstExpression.(ast.Expression)) + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + var nextValue ast.Node + for parser.hasNext() { + if parser.matchDirectValue(lexer.CloseParentheses) { + break + } + newLinesRemoveError = parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + + nextValue, parsingError = parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + if _, ok := nextValue.(ast.Expression); !ok { + return nil, parser.expectingExpressionError(ParenthesesExpression) + } + values = append(values, nextValue.(ast.Expression)) + newLinesRemoveError = parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + if parser.matchDirectValue(lexer.Comma) { + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + } else if !parser.matchDirectValue(lexer.CloseParentheses) { + return nil, parser.newSyntaxError(TupleExpression) + } + } + newLinesRemoveError = parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + if !parser.matchDirectValue(lexer.CloseParentheses) { + return nil, parser.expressionNeverClosedError(TupleExpression) + } + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + return &ast.TupleExpression{ + Values: values, + }, nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-pass-statement.go b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-pass-statement.go new file mode 100644 index 0000000..b43376b --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-pass-statement.go @@ -0,0 +1,13 @@ +package parser + +import ( + "github.com/shoriwe/gplasma/pkg/ast" +) + +func (parser *Parser) parsePassStatement() (*ast.PassStatement, error) { + tokenizingError := parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + return &ast.PassStatement{}, nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-return-statement.go b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-return-statement.go new file mode 100644 index 0000000..42d1731 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-return-statement.go @@ -0,0 +1,43 @@ +package parser + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/lexer" +) + +func (parser *Parser) parseReturnStatement() (*ast.ReturnStatement, error) { + tokenizingError := parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + newLinesRemoveError := parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + var results []ast.Expression + for parser.hasNext() { + if parser.matchKind(lexer.Separator) || parser.matchKind(lexer.EOF) { + break + } + + result, parsingError := parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + if _, ok := result.(ast.Expression); !ok { + return nil, parser.expectingExpressionError(ReturnStatement) + } + results = append(results, result.(ast.Expression)) + if parser.matchDirectValue(lexer.Comma) { + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + } else if !(parser.matchKind(lexer.Separator) || parser.matchKind(lexer.EOF)) { + return nil, parser.newSyntaxError(ReturnStatement) + } + } + return &ast.ReturnStatement{ + Results: results, + }, nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-selector-expression.go b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-selector-expression.go new file mode 100644 index 0000000..79e72cd --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-selector-expression.go @@ -0,0 +1,34 @@ +package parser + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/lexer" +) + +func (parser *Parser) parseSelectorExpression(expression ast.Expression) (*ast.SelectorExpression, error) { + selector := expression + for parser.hasNext() { + if !parser.matchDirectValue(lexer.Dot) { + break + } + tokenizingError := parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + identifier := parser.currentToken + if identifier.Kind != lexer.IdentifierKind { + return nil, parser.newSyntaxError(SelectorExpression) + } + selector = &ast.SelectorExpression{ + X: selector, + Identifier: &ast.Identifier{ + Token: identifier, + }, + } + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + } + return selector.(*ast.SelectorExpression), nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-super-statement.go b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-super-statement.go new file mode 100644 index 0000000..24a38b2 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-super-statement.go @@ -0,0 +1,20 @@ +package parser + +import "github.com/shoriwe/gplasma/pkg/ast" + +func (parser *Parser) parseSuperExpression() (*ast.SuperExpression, error) { + tokenizingError := parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + x, parsingError := parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + if _, ok := x.(ast.Expression); !ok { + return nil, parser.expectingExpressionError(SuperExpression) + } + return &ast.SuperExpression{ + X: x.(ast.Expression), + }, nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-switch-statement.go b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-switch-statement.go new file mode 100644 index 0000000..fc7780b --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-switch-statement.go @@ -0,0 +1,144 @@ +package parser + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/lexer" +) + +func (parser *Parser) parseSwitchStatement() (*ast.SwitchStatement, error) { + tokenizingError := parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + newLinesRemoveError := parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + + target, parsingError := parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + if _, ok := target.(ast.Expression); !ok { + return nil, parser.expectingExpressionError(SwitchStatement) + } + if !parser.matchDirectValue(lexer.NewLine) { + return nil, parser.newSyntaxError(SwitchStatement) + } + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + // parse Cases + var caseBlocks []*ast.CaseBlock + if parser.matchDirectValue(lexer.Case) { + for parser.hasNext() { + if parser.matchDirectValue(lexer.Default) || + parser.matchDirectValue(lexer.End) { + break + } + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + newLinesRemoveError = parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + var cases []ast.Expression + var caseTarget ast.Node + for parser.hasNext() { + caseTarget, parsingError = parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + if _, ok := caseTarget.(ast.Expression); !ok { + return nil, parser.expectingExpressionError(CaseBlock) + } + cases = append(cases, caseTarget.(ast.Expression)) + if parser.matchDirectValue(lexer.NewLine) { + break + } else if parser.matchDirectValue(lexer.Comma) { + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + } else { + return nil, parser.newSyntaxError(CaseBlock) + } + } + if !parser.matchDirectValue(lexer.NewLine) { + return nil, parser.newSyntaxError(CaseBlock) + } + // Targets Body + var caseBody []ast.Node + var caseBodyNode ast.Node + for parser.hasNext() { + if parser.matchKind(lexer.Separator) { + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + if parser.matchDirectValue(lexer.Case) || + parser.matchDirectValue(lexer.Default) || + parser.matchDirectValue(lexer.End) { + break + } + continue + } + caseBodyNode, parsingError = parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + caseBody = append(caseBody, caseBodyNode) + } + // Targets block + caseBlocks = append(caseBlocks, &ast.CaseBlock{ + Cases: cases, + Body: caseBody, + }) + } + } + // Parse Default + var defaultBody []ast.Node + if parser.matchDirectValue(lexer.Default) { + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + if !parser.matchDirectValue(lexer.NewLine) { + return nil, parser.newSyntaxError(DefaultBlock) + } + var defaultBodyNode ast.Node + for parser.hasNext() { + if parser.matchKind(lexer.Separator) { + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + if parser.matchDirectValue(lexer.End) { + break + } + continue + } + defaultBodyNode, parsingError = parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + defaultBody = append(defaultBody, defaultBodyNode) + } + } + // Finally detect valid end + if !parser.matchDirectValue(lexer.End) { + return nil, parser.statementNeverEndedError(SwitchStatement) + } + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + return &ast.SwitchStatement{ + Target: target.(ast.Expression), + CaseBlocks: caseBlocks, + Default: defaultBody, + }, nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-unary-expression.go b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-unary-expression.go new file mode 100644 index 0000000..7e84181 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-unary-expression.go @@ -0,0 +1,33 @@ +package parser + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/lexer" +) + +func (parser *Parser) parseUnaryExpression() (ast.Node, error) { + // Do something to parse Unary + if parser.matchKind(lexer.Operator) { + switch parser.currentToken.DirectValue { + case lexer.Sub, lexer.Add, lexer.NegateBits, lexer.SignNot, lexer.Not: + operator := parser.currentToken + tokenizingError := parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + + x, parsingError := parser.parseUnaryExpression() + if parsingError != nil { + return nil, parsingError + } + if _, ok := x.(ast.Expression); !ok { + return nil, parser.expectingExpressionError(PointerExpression) + } + return &ast.UnaryExpression{ + Operator: operator, + X: x.(ast.Expression), + }, nil + } + } + return parser.parsePrimaryExpression() +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-unless-one-liner-expression.go b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-unless-one-liner-expression.go new file mode 100644 index 0000000..8775922 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-unless-one-liner-expression.go @@ -0,0 +1,54 @@ +package parser + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/lexer" +) + +func (parser *Parser) parseUnlessOneLinerExpression(result ast.Expression) (*ast.UnlessOneLinerExpression, error) { + tokenizingError := parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + newLinesRemoveError := parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + + condition, parsingError := parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + if _, ok := condition.(ast.Expression); !ok { + return nil, parser.expectingExpressionError(UnlessOneLinerExpression) + } + if !parser.matchDirectValue(lexer.Else) { + return &ast.UnlessOneLinerExpression{ + Result: result, + Condition: condition.(ast.Expression), + ElseResult: nil, + }, nil + } + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + newLinesRemoveError = parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + var elseResult ast.Node + + elseResult, parsingError = parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + if _, ok := condition.(ast.Expression); !ok { + return nil, parser.expectingExpressionError(OneLineElseBlock) + } + return &ast.UnlessOneLinerExpression{ + Result: result, + Condition: condition.(ast.Expression), + ElseResult: elseResult.(ast.Expression), + }, nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-unless-statement.go b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-unless-statement.go new file mode 100644 index 0000000..429aab4 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-unless-statement.go @@ -0,0 +1,141 @@ +package parser + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/lexer" +) + +func (parser *Parser) parseUnlessStatement() (*ast.UnlessStatement, error) { + tokenizingError := parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + newLinesRemoveError := parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + + condition, parsingError := parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + if _, ok := condition.(ast.Expression); !ok { + return nil, parser.expectingExpressionError(UnlessStatement) + } + if !parser.matchDirectValue(lexer.NewLine) { + return nil, parser.newSyntaxError(UnlessStatement) + } + // Parse Unless + root := &ast.UnlessStatement{ + Condition: condition.(ast.Expression), + Body: []ast.Node{}, + Else: []ast.Node{}, + } + var bodyNode ast.Node + for parser.hasNext() { + if parser.matchKind(lexer.Separator) { + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + if parser.matchDirectValue(lexer.Elif) || + parser.matchDirectValue(lexer.Else) || + parser.matchDirectValue(lexer.End) { + break + } + continue + } + bodyNode, parsingError = parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + root.Body = append(root.Body, bodyNode) + } + // Parse Elifs + lastCondition := root + if parser.matchDirectValue(lexer.Elif) { + elifBlocksParsingLoop: + for parser.hasNext() { + block := ast.ElifBlock{ + Condition: nil, + Body: nil, + } + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + condition, parsingError = parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + if _, ok := condition.(ast.Expression); !ok { + return nil, parser.expectingExpressionError(ElifBlock) + } + block.Condition = condition.(ast.Expression) + if !parser.matchDirectValue(lexer.NewLine) { + return nil, parser.newSyntaxError(IfStatement) + } + for parser.hasNext() { + if parser.matchKind(lexer.Separator) { + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + if parser.matchDirectValue(lexer.Else) || + parser.matchDirectValue(lexer.End) { + root.ElifBlocks = append(root.ElifBlocks, block) + break elifBlocksParsingLoop + } else if parser.matchDirectValue(lexer.Elif) { + break + } + continue + } + bodyNode, parsingError = parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + block.Body = append(block.Body, bodyNode) + } + if !parser.matchDirectValue(lexer.Elif) { + return nil, parser.newSyntaxError(ElifBlock) + } + root.ElifBlocks = append(root.ElifBlocks, block) + } + } + // Parse Default + if parser.matchDirectValue(lexer.Else) { + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + var elseBodyNode ast.Node + if !parser.matchDirectValue(lexer.NewLine) { + return nil, parser.newSyntaxError(ElseBlock) + } + for parser.hasNext() { + if parser.matchKind(lexer.Separator) { + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + if parser.matchDirectValue(lexer.End) { + break + } + continue + } + elseBodyNode, parsingError = parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + lastCondition.Else = append(lastCondition.Else, elseBodyNode) + } + } + if !parser.matchDirectValue(lexer.End) { + return nil, parser.statementNeverEndedError(UnlessStatement) + } + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + return root, nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-until-statement.go b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-until-statement.go new file mode 100644 index 0000000..68bcfe0 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-until-statement.go @@ -0,0 +1,61 @@ +package parser + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/lexer" +) + +func (parser *Parser) parseUntilStatement() (*ast.UntilLoopStatement, error) { + tokenizingError := parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + newLinesRemoveError := parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + condition, parsingError := parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + if _, ok := condition.(ast.Expression); !ok { + return nil, parser.newSyntaxError(UntilStatement) + } + if !parser.matchDirectValue(lexer.NewLine) { + return nil, parser.newSyntaxError(UntilStatement) + } + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + var bodyNode ast.Node + var body []ast.Node + for parser.hasNext() { + if parser.matchKind(lexer.Separator) { + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + if parser.matchDirectValue(lexer.End) { + break + } + continue + } + bodyNode, parsingError = parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + body = append(body, bodyNode) + } + if !parser.matchDirectValue(lexer.End) { + return nil, parser.statementNeverEndedError(UntilStatement) + } + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + return &ast.UntilLoopStatement{ + Condition: condition.(ast.Expression), + Body: body, + }, nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-while-statement.go b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-while-statement.go new file mode 100644 index 0000000..3dfe241 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-while-statement.go @@ -0,0 +1,57 @@ +package parser + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/lexer" +) + +func (parser *Parser) parseWhileStatement() (*ast.WhileLoopStatement, error) { + tokenizingError := parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + condition, parsingError := parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + if _, ok := condition.(ast.Expression); !ok { + return nil, parser.newSyntaxError(WhileStatement) + } + if !parser.matchDirectValue(lexer.NewLine) { + return nil, parser.newSyntaxError(WhileStatement) + } + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + var whileChild ast.Node + var body []ast.Node + for parser.hasNext() { + if parser.matchKind(lexer.Separator) { + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + if parser.matchDirectValue(lexer.End) { + break + } + continue + } + whileChild, parsingError = parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + body = append(body, whileChild) + } + if !parser.matchDirectValue(lexer.End) { + return nil, parser.statementNeverEndedError(WhileStatement) + } + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + return &ast.WhileLoopStatement{ + Condition: condition.(ast.Expression), + Body: body, + }, nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-yield-statement.go b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-yield-statement.go new file mode 100644 index 0000000..3a62536 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/parser/parse-yield-statement.go @@ -0,0 +1,43 @@ +package parser + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/lexer" +) + +func (parser *Parser) parseYieldStatement() (*ast.YieldStatement, error) { + tokenizingError := parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + newLinesRemoveError := parser.removeNewLines() + if newLinesRemoveError != nil { + return nil, newLinesRemoveError + } + var results []ast.Expression + for parser.hasNext() { + if parser.matchKind(lexer.Separator) || parser.matchKind(lexer.EOF) { + break + } + + result, parsingError := parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + if _, ok := result.(ast.Expression); !ok { + return nil, parser.expectingExpressionError(YieldStatement) + } + results = append(results, result.(ast.Expression)) + if parser.matchDirectValue(lexer.Comma) { + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + } else if !(parser.matchKind(lexer.Separator) || parser.matchKind(lexer.EOF)) { + return nil, parser.newSyntaxError(YieldStatement) + } + } + return &ast.YieldStatement{ + Results: results, + }, nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/parser/parser-primary-expression.go b/vendor/github.com/shoriwe/gplasma/pkg/parser/parser-primary-expression.go new file mode 100644 index 0000000..0f5cbe1 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/parser/parser-primary-expression.go @@ -0,0 +1,39 @@ +package parser + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/lexer" +) + +func (parser *Parser) parsePrimaryExpression() (ast.Node, error) { + var parsedNode ast.Node + var parsingError error + parsedNode, parsingError = parser.parseOperand() + if parsingError != nil { + return nil, parsingError + } +expressionPendingLoop: + for { + switch parser.currentToken.DirectValue { + case lexer.Dot: // Is selector + parsedNode, parsingError = parser.parseSelectorExpression(parsedNode.(ast.Expression)) + case lexer.OpenParentheses: // Is function Call + parsedNode, parsingError = parser.parseMethodInvocationExpression(parsedNode.(ast.Expression)) + case lexer.OpenSquareBracket: // Is indexing + parsedNode, parsingError = parser.parseIndexExpression(parsedNode.(ast.Expression)) + case lexer.If: // One line If + parsedNode, parsingError = parser.parseIfOneLinerExpression(parsedNode.(ast.Expression)) + case lexer.Unless: // One line Unless + parsedNode, parsingError = parser.parseUnlessOneLinerExpression(parsedNode.(ast.Expression)) + default: + if parser.matchKind(lexer.Assignment) { + parsedNode, parsingError = parser.parseAssignmentStatement(parsedNode.(ast.Expression)) + } + break expressionPendingLoop + } + } + if parsingError != nil { + return nil, parsingError + } + return parsedNode, nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/parser/parser.go b/vendor/github.com/shoriwe/gplasma/pkg/parser/parser.go new file mode 100644 index 0000000..2c2a5d1 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/parser/parser.go @@ -0,0 +1,78 @@ +package parser + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/common" + "github.com/shoriwe/gplasma/pkg/lexer" +) + +type Parser struct { + lineStack common.ListStack[int] + lexer *lexer.Lexer + complete bool + currentToken *lexer.Token +} + +func (parser *Parser) Parse() (*ast.Program, error) { + result := &ast.Program{ + Begin: nil, + End: nil, + Body: nil, + } + tokenizingError := parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + var ( + beginStatement *ast.BeginStatement + endStatement *ast.EndStatement + parsedExpression ast.Node + parsingError error + ) + for parser.hasNext() { + if parser.matchKind(lexer.Separator) { + tokenizingError = parser.next() + if tokenizingError != nil { + return nil, tokenizingError + } + continue + } + switch { + case parser.matchDirectValue(lexer.BEGIN): + if result.Begin != nil { + return nil, BeginRepeated + } + beginStatement, parsingError = parser.parseBeginStatement() + if parsingError != nil { + return nil, parsingError + } + result.Begin = beginStatement + case parser.matchDirectValue(lexer.END): + if result.End != nil { + return nil, EndRepeated + } + endStatement, parsingError = parser.parseEndStatement() + if parsingError != nil { + return nil, parsingError + } + result.End = endStatement + default: + parsedExpression, parsingError = parser.parseBinaryExpression(0) + if parsingError != nil { + return nil, parsingError + } + result.Body = append(result.Body, parsedExpression) + } + } + parser.complete = true + return result, nil +} + +func NewParser(lexer_ *lexer.Lexer) *Parser { + return &Parser{ + lineStack: common.ListStack[int]{}, + lexer: lexer_, + complete: false, + currentToken: nil, + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/checks/checks.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/checks/checks.go new file mode 100644 index 0000000..f04ecf6 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/checks/checks.go @@ -0,0 +1,125 @@ +package checks + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/common" +) + +/* +Check verifies: +- Yield statement is only on generator statements +- Break/Continue/Redo are only in loop statements +- Return statement is only on functions and generator statements +*/ +type Check struct { + InvalidFunctionNodesStack common.ListStack[ast.Node] + InvalidGeneratorNodesStack common.ListStack[ast.Node] + InvalidLoopNodesStack common.ListStack[ast.Node] + insideFunction bool + insideGenerator bool + insideLoop bool +} + +func (c *Check) Visit(node ast.Node) ast.Visitor { + defer func(oldInsideFunction, oldInsideGenerator, oldInsideLoop bool) { + c.insideFunction, c.insideGenerator, c.insideLoop = oldInsideFunction, oldInsideGenerator, oldInsideLoop + }(c.insideFunction, c.insideGenerator, c.insideLoop) + switch n := node.(type) { + case *ast.FunctionDefinitionStatement: + c.insideFunction = true + c.insideGenerator = false + c.insideLoop = false + for _, child := range n.Body { + c.Visit(child) + } + return nil + case *ast.GeneratorDefinitionStatement: + c.insideFunction = false + c.insideGenerator = true + c.insideLoop = false + for _, child := range n.Body { + c.Visit(child) + } + return nil + case *ast.ForLoopStatement: + c.insideLoop = true + for _, child := range n.Body { + c.Visit(child) + } + return nil + case *ast.WhileLoopStatement: + c.insideLoop = true + for _, child := range n.Body { + c.Visit(child) + } + return nil + case *ast.DoWhileStatement: + c.insideLoop = true + for _, child := range n.Body { + c.Visit(child) + } + return nil + case *ast.UntilLoopStatement: + c.insideLoop = true + for _, child := range n.Body { + c.Visit(child) + } + return nil + case *ast.ReturnStatement: + if !c.insideFunction && !c.insideGenerator { + c.InvalidFunctionNodesStack.Push(n) + } + return nil + case *ast.YieldStatement: + if !c.insideGenerator { + c.InvalidGeneratorNodesStack.Push(n) + } + return nil + case *ast.DeferStatement: + if !c.insideFunction && !c.insideGenerator { + c.InvalidFunctionNodesStack.Push(n) + } + return nil + case *ast.BreakStatement, *ast.ContinueStatement: + if !c.insideLoop { + c.InvalidLoopNodesStack.Push(n) + } + return nil + } + return c +} + +func (c *Check) CountInvalidFunctionNodes() int { + result := 0 + for current := c.InvalidFunctionNodesStack.Top; current != nil; current = current.Next { + result++ + } + return result +} + +func (c *Check) CountInvalidGeneratorNodes() int { + result := 0 + for current := c.InvalidGeneratorNodesStack.Top; current != nil; current = current.Next { + result++ + } + return result +} + +func (c *Check) CountInvalidLoopNodes() int { + result := 0 + for current := c.InvalidLoopNodesStack.Top; current != nil; current = current.Next { + result++ + } + return result +} + +func NewCheckPass() *Check { + return &Check{ + InvalidFunctionNodesStack: common.ListStack[ast.Node]{}, + InvalidGeneratorNodesStack: common.ListStack[ast.Node]{}, + InvalidLoopNodesStack: common.ListStack[ast.Node]{}, + insideFunction: false, + insideGenerator: false, + insideLoop: false, + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/checks/invalid-break.pm b/vendor/github.com/shoriwe/gplasma/pkg/passes/checks/invalid-break.pm new file mode 100644 index 0000000..91b7628 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/checks/invalid-break.pm @@ -0,0 +1,23 @@ +break # 1 + +def my_function() + break # 2 +end + +gen my_generator() + break # 3 +end + +for a in range(100) + break +end + +for value in range(2000) + gen __anonymous() + break # 4 + end +end + +if false + break # 5 +end \ No newline at end of file diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/checks/invalid-continue.pm b/vendor/github.com/shoriwe/gplasma/pkg/passes/checks/invalid-continue.pm new file mode 100644 index 0000000..2c2a90e --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/checks/invalid-continue.pm @@ -0,0 +1,23 @@ +continue # 1 + +def my_function() + continue # 2 +end + +gen my_generator() + continue # 3 +end + +for a in range(100) + continue +end + +for value in range(2000) + gen __anonymous() + continue # 4 + end +end + +if false + continue # 5 +end \ No newline at end of file diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/checks/invalid-return.pm b/vendor/github.com/shoriwe/gplasma/pkg/passes/checks/invalid-return.pm new file mode 100644 index 0000000..1bdf01f --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/checks/invalid-return.pm @@ -0,0 +1,26 @@ +return 1 + +def my_function() + return none +end + +gen my_generator() + defer yes() + return none +end + +defer no() + +for a in range(100) + return 2 +end + +for value in range(2000) + def __anonymous() + return value + end +end + +if false + return 3 +end \ No newline at end of file diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/checks/invalid-yield.pm b/vendor/github.com/shoriwe/gplasma/pkg/passes/checks/invalid-yield.pm new file mode 100644 index 0000000..0b06b26 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/checks/invalid-yield.pm @@ -0,0 +1,23 @@ +yield 1 + +def my_function() + yield 2 +end + +gen my_generator() + yield none +end + +for a in range(100) + yield 3 +end + +for value in range(2000) + gen __anonymous() + yield value + end +end + +if false + yield 4 +end \ No newline at end of file diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/checks/valid-script.pm b/vendor/github.com/shoriwe/gplasma/pkg/passes/checks/valid-script.pm new file mode 100644 index 0000000..12a18e0 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/checks/valid-script.pm @@ -0,0 +1,11 @@ +BEGIN + println("welcome") +end + +for a in range(100) + break +end + +END + println("this is the end") +end \ No newline at end of file diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/anon-identifier.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/anon-identifier.go new file mode 100644 index 0000000..1ad7d8c --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/anon-identifier.go @@ -0,0 +1,14 @@ +package simplification + +import ( + "fmt" + "github.com/shoriwe/gplasma/pkg/ast2" +) + +func (simplify *simplifyPass) nextAnonIdentifier() *ast2.Identifier { + ident := simplify.currentAnonIdent + simplify.currentAnonIdent++ + return &ast2.Identifier{ + Symbol: fmt.Sprintf("____simplify_%d", ident), + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-array.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-array.go new file mode 100644 index 0000000..3d7b030 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-array.go @@ -0,0 +1,16 @@ +package simplification + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/ast2" +) + +func (simplify *simplifyPass) Array(array *ast.ArrayExpression) *ast2.Array { + values := make([]ast2.Expression, 0, len(array.Values)) + for _, value := range array.Values { + values = append(values, simplify.Expression(value)) + } + return &ast2.Array{ + Values: values, + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-assign.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-assign.go new file mode 100644 index 0000000..ecfe2fb --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-assign.go @@ -0,0 +1,107 @@ +package simplification + +import ( + "fmt" + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/ast2" + "github.com/shoriwe/gplasma/pkg/lexer" +) + +func (simplify *simplifyPass) Assign(assign *ast.AssignStatement) *ast2.Assignment { + var ( + left ast2.Assignable + right = simplify.Expression(assign.RightHandSide) + ) + switch l := assign.LeftHandSide.(type) { + case *ast.Identifier: + left = simplify.Identifier(l) + case *ast.SelectorExpression: + left = simplify.Selector(l) + case *ast.IndexExpression: + left = simplify.Index(l) + default: + panic("invalid identifier left hand side type") + } + switch assign.AssignOperator.DirectValue { + case lexer.Assign: + break + case lexer.BitwiseOrAssign: + right = &ast2.Binary{ + Left: left, + Right: right, + Operator: ast2.BitwiseOr, + } + case lexer.BitwiseXorAssign: + right = &ast2.Binary{ + Left: left, + Right: right, + Operator: ast2.BitwiseXor, + } + case lexer.BitwiseAndAssign: + right = &ast2.Binary{ + Left: left, + Right: right, + Operator: ast2.BitwiseAnd, + } + case lexer.BitwiseLeftAssign: + right = &ast2.Binary{ + Left: left, + Right: right, + Operator: ast2.BitwiseLeft, + } + case lexer.BitwiseRightAssign: + right = &ast2.Binary{ + Left: left, + Right: right, + Operator: ast2.BitwiseRight, + } + case lexer.AddAssign: + right = &ast2.Binary{ + Left: left, + Right: right, + Operator: ast2.Add, + } + case lexer.SubAssign: + right = &ast2.Binary{ + Left: left, + Right: right, + Operator: ast2.Sub, + } + case lexer.StarAssign: + right = &ast2.Binary{ + Left: left, + Right: right, + Operator: ast2.Mul, + } + case lexer.DivAssign: + right = &ast2.Binary{ + Left: left, + Right: right, + Operator: ast2.Div, + } + case lexer.FloorDivAssign: + right = &ast2.Binary{ + Left: left, + Right: right, + Operator: ast2.FloorDiv, + } + case lexer.ModulusAssign: + right = &ast2.Binary{ + Left: left, + Right: right, + Operator: ast2.Modulus, + } + case lexer.PowerOfAssign: + right = &ast2.Binary{ + Left: left, + Right: right, + Operator: ast2.PowerOf, + } + default: + panic(fmt.Sprintf("unknown binary operator for assignment %d", assign.AssignOperator.DirectValue)) + } + return &ast2.Assignment{ + Left: left, + Right: right, + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-binary.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-binary.go new file mode 100644 index 0000000..ea26d84 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-binary.go @@ -0,0 +1,69 @@ +package simplification + +import ( + "fmt" + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/ast2" + "github.com/shoriwe/gplasma/pkg/lexer" +) + +func (simplify *simplifyPass) Binary(binary *ast.BinaryExpression) *ast2.Binary { + var operator ast2.BinaryOperator + switch binary.Operator.DirectValue { + case lexer.And: + operator = ast2.And + case lexer.Or: + operator = ast2.Or + case lexer.Xor: + operator = ast2.Xor + case lexer.In: + operator = ast2.In + case lexer.Is: + operator = ast2.Is + case lexer.Implements: + operator = ast2.Implements + case lexer.Equals: + operator = ast2.Equals + case lexer.NotEqual: + operator = ast2.NotEqual + case lexer.GreaterThan: + operator = ast2.GreaterThan + case lexer.GreaterOrEqualThan: + operator = ast2.GreaterOrEqualThan + case lexer.LessThan: + operator = ast2.LessThan + case lexer.LessOrEqualThan: + operator = ast2.LessOrEqualThan + case lexer.BitwiseOr: + operator = ast2.BitwiseOr + case lexer.BitwiseXor: + operator = ast2.BitwiseXor + case lexer.BitwiseAnd: + operator = ast2.BitwiseAnd + case lexer.BitwiseLeft: + operator = ast2.BitwiseLeft + case lexer.BitwiseRight: + operator = ast2.BitwiseRight + case lexer.Add: + operator = ast2.Add + case lexer.Sub: + operator = ast2.Sub + case lexer.Star: + operator = ast2.Mul + case lexer.Div: + operator = ast2.Div + case lexer.FloorDiv: + operator = ast2.FloorDiv + case lexer.Modulus: + operator = ast2.Modulus + case lexer.PowerOf: + operator = ast2.PowerOf + default: + panic(fmt.Sprintf("unknown binary operator %d", binary.Operator.DirectValue)) + } + return &ast2.Binary{ + Left: simplify.Expression(binary.LeftHandSide), + Right: simplify.Expression(binary.RightHandSide), + Operator: operator, + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-call.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-call.go new file mode 100644 index 0000000..38346e2 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-call.go @@ -0,0 +1,17 @@ +package simplification + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/ast2" +) + +func (simplify *simplifyPass) Call(call *ast.MethodInvocationExpression) *ast2.FunctionCall { + arguments := make([]ast2.Expression, 0, len(call.Arguments)) + for _, argument := range call.Arguments { + arguments = append(arguments, simplify.Expression(argument)) + } + return &ast2.FunctionCall{ + Function: simplify.Expression(call.Function), + Arguments: arguments, + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-class.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-class.go new file mode 100644 index 0000000..15ecfe3 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-class.go @@ -0,0 +1,22 @@ +package simplification + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/ast2" +) + +func (simplify *simplifyPass) Class(class *ast.ClassStatement) *ast2.Class { + bases := make([]ast2.Expression, 0, len(class.Bases)) + for _, base := range class.Bases { + bases = append(bases, simplify.Expression(base)) + } + body := make([]ast2.Node, 0, len(class.Body)) + for _, node := range class.Body { + body = append(body, simplify.Node(node)) + } + return &ast2.Class{ + Name: simplify.Identifier(class.Name), + Bases: bases, + Body: body, + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-defer.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-defer.go new file mode 100644 index 0000000..5514816 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-defer.go @@ -0,0 +1,12 @@ +package simplification + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/ast2" +) + +func (simplify *simplifyPass) Defer(d *ast.DeferStatement) *ast2.Defer { + return &ast2.Defer{ + X: simplify.Expression(d.X), + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-delete.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-delete.go new file mode 100644 index 0000000..4c77181 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-delete.go @@ -0,0 +1,23 @@ +package simplification + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/ast2" +) + +func (simplify *simplifyPass) Delete(del *ast.DeleteStatement) *ast2.Delete { + var x ast2.Assignable + switch dx := del.X.(type) { + case *ast.Identifier: + x = simplify.Identifier(dx) + case *ast.IndexExpression: + x = simplify.Index(dx) + case *ast.SelectorExpression: + x = simplify.Selector(dx) + default: + panic("unknown selector type") + } + return &ast2.Delete{ + X: x, + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-do-while.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-do-while.go new file mode 100644 index 0000000..765a631 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-do-while.go @@ -0,0 +1,20 @@ +package simplification + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/ast2" +) + +func (simplify *simplifyPass) DoWhile(do *ast.DoWhileStatement) *ast2.DoWhile { + var ( + body = make([]ast2.Node, 0, len(do.Body)) + condition = simplify.Expression(do.Condition) + ) + for _, node := range do.Body { + body = append(body, simplify.Node(node)) + } + return &ast2.DoWhile{ + Body: body, + Condition: condition, + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-expression.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-expression.go new file mode 100644 index 0000000..cb3d688 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-expression.go @@ -0,0 +1,50 @@ +package simplification + +import ( + "fmt" + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/ast2" + "reflect" +) + +func (simplify *simplifyPass) Expression(expr ast.Expression) ast2.Expression { + if expr == nil { + return &ast2.None{} + } + switch e := expr.(type) { + case *ast.ArrayExpression: + return simplify.Array(e) + case *ast.TupleExpression: + return simplify.Tuple(e) + case *ast.HashExpression: + return simplify.Hash(e) + case *ast.Identifier: + return simplify.Identifier(e) + case *ast.BasicLiteralExpression: + return simplify.Literal(e) + case *ast.BinaryExpression: + return simplify.Binary(e) + case *ast.UnaryExpression: + return simplify.Unary(e) + case *ast.ParenthesesExpression: + return simplify.Parentheses(e) + case *ast.LambdaExpression: + return simplify.Lambda(e) + case *ast.GeneratorExpression: + return simplify.GeneratorExpr(e) + case *ast.SelectorExpression: + return simplify.Selector(e) + case *ast.MethodInvocationExpression: + return simplify.Call(e) + case *ast.IndexExpression: + return simplify.Index(e) + case *ast.IfOneLinerExpression: + return simplify.IfOneLiner(e) + case *ast.UnlessOneLinerExpression: + return simplify.UnlessOneLiner(e) + case *ast.SuperExpression: + return simplify.Super(e) + default: + panic(fmt.Sprintf("unknown expression type %s", reflect.TypeOf(expr).String())) + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-for.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-for.go new file mode 100644 index 0000000..bb09067 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-for.go @@ -0,0 +1,75 @@ +package simplification + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/ast2" + "github.com/shoriwe/gplasma/pkg/common/magic-functions" +) + +func (simplify *simplifyPass) For(for_ *ast.ForLoopStatement) *ast2.While { + sourceIdentifier := simplify.nextAnonIdentifier() + sourceAssignment := &ast2.Assignment{ + Statement: nil, + Left: sourceIdentifier, + Right: &ast2.FunctionCall{ + Function: &ast2.Selector{ + X: simplify.Expression(for_.Source), + Identifier: &ast2.Identifier{ + Symbol: magic_functions.Iter, + }, + }, + }, + } + anonymousIdentifier := simplify.nextAnonIdentifier() + hasNext := &ast2.FunctionCall{ + Function: &ast2.Selector{ + X: sourceIdentifier, + Identifier: &ast2.Identifier{ + Symbol: magic_functions.HasNext, + }, + }, + Arguments: nil, + } + next := &ast2.Assignment{ + Left: anonymousIdentifier, + Right: &ast2.FunctionCall{ + Function: &ast2.Selector{ + X: sourceIdentifier, + Identifier: &ast2.Identifier{ + Symbol: magic_functions.Next, + }, + }, + Arguments: nil, + }, + } + expand := make([]ast2.Node, 0, len(for_.Receivers)) + if len(for_.Receivers) > 1 { + for index, receiver := range for_.Receivers { + expand = append(expand, &ast2.Assignment{ + Left: simplify.Identifier(receiver), + Right: &ast2.Index{ + Source: anonymousIdentifier, + Index: &ast2.Integer{ + Value: int64(index), + }, + }, + }) + } + } else { + expand = append(expand, &ast2.Assignment{ + Left: simplify.Identifier(for_.Receivers[0]), + Right: anonymousIdentifier, + }) + } + body := make([]ast2.Node, 0, 1+len(expand)+len(for_.Body)) + body = append(body, next) + body = append(body, expand...) + for _, node := range for_.Body { + body = append(body, simplify.Node(node)) + } + return &ast2.While{ + Setup: []ast2.Node{sourceAssignment}, + Condition: hasNext, + Body: body, + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-function.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-function.go new file mode 100644 index 0000000..b02ab34 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-function.go @@ -0,0 +1,22 @@ +package simplification + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/ast2" +) + +func (simplify *simplifyPass) Function(f *ast.FunctionDefinitionStatement) *ast2.FunctionDefinition { + arguments := make([]*ast2.Identifier, 0, len(f.Arguments)) + for _, argument := range f.Arguments { + arguments = append(arguments, simplify.Identifier(argument)) + } + body := make([]ast2.Node, 0, len(f.Body)) + for _, node := range f.Body { + body = append(body, simplify.Node(node)) + } + return &ast2.FunctionDefinition{ + Name: simplify.Identifier(f.Name), + Arguments: arguments, + Body: body, + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-generator.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-generator.go new file mode 100644 index 0000000..2bbe08c --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-generator.go @@ -0,0 +1,34 @@ +package simplification + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/ast2" +) + +func (simplify *simplifyPass) GeneratorExpr(generator *ast.GeneratorExpression) *ast2.Generator { + receivers := make([]*ast2.Identifier, 0, len(generator.Receivers)) + for _, receiver := range generator.Receivers { + receivers = append(receivers, simplify.Identifier(receiver)) + } + return &ast2.Generator{ + Operation: simplify.Expression(generator.Operation), + Receivers: receivers, + Source: simplify.Expression(generator.Source), + } +} + +func (simplify *simplifyPass) GeneratorDef(generator *ast.GeneratorDefinitionStatement) *ast2.GeneratorDefinition { + arguments := make([]*ast2.Identifier, 0, len(generator.Arguments)) + for _, argument := range generator.Arguments { + arguments = append(arguments, simplify.Identifier(argument)) + } + body := make([]ast2.Node, 0, len(generator.Body)) + for _, node := range generator.Body { + body = append(body, simplify.Node(node)) + } + return &ast2.GeneratorDefinition{ + Name: simplify.Identifier(generator.Name), + Arguments: arguments, + Body: body, + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-hash.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-hash.go new file mode 100644 index 0000000..832dc1b --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-hash.go @@ -0,0 +1,19 @@ +package simplification + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/ast2" +) + +func (simplify *simplifyPass) Hash(hash *ast.HashExpression) *ast2.Hash { + values := make([]*ast2.KeyValue, 0, len(hash.Values)) + for _, value := range hash.Values { + values = append(values, &ast2.KeyValue{ + Key: simplify.Expression(value.Key), + Value: simplify.Expression(value.Value), + }) + } + return &ast2.Hash{ + Values: values, + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-identifier.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-identifier.go new file mode 100644 index 0000000..f6ac29a --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-identifier.go @@ -0,0 +1,12 @@ +package simplification + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/ast2" +) + +func (simplify *simplifyPass) Identifier(ident *ast.Identifier) *ast2.Identifier { + return &ast2.Identifier{ + Symbol: ident.Token.String(), + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-if-one-liner.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-if-one-liner.go new file mode 100644 index 0000000..eaf5497 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-if-one-liner.go @@ -0,0 +1,25 @@ +package simplification + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/ast2" +) + +func (simplify *simplifyPass) IfOneLiner(if_ *ast.IfOneLinerExpression) *ast2.IfOneLiner { + return &ast2.IfOneLiner{ + Condition: simplify.Expression(if_.Condition), + Result: simplify.Expression(if_.Result), + Else: simplify.Expression(if_.ElseResult), + } +} + +func (simplify *simplifyPass) UnlessOneLiner(unless *ast.UnlessOneLinerExpression) *ast2.IfOneLiner { + return &ast2.IfOneLiner{ + Condition: &ast2.Unary{ + Operator: ast2.Not, + X: simplify.Expression(unless.Condition), + }, + Result: simplify.Expression(unless.Result), + Else: simplify.Expression(unless.ElseResult), + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-if.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-if.go new file mode 100644 index 0000000..bcc76ff --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-if.go @@ -0,0 +1,37 @@ +package simplification + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/ast2" +) + +func (simplify *simplifyPass) If(if_ *ast.IfStatement) *ast2.If { + body := make([]ast2.Node, 0, len(if_.Body)) + for _, node := range if_.Body { + body = append(body, simplify.Node(node)) + } + root := &ast2.If{ + Condition: simplify.Expression(if_.Condition), + Body: body, + Else: nil, + } + lastIf := root + for _, elif := range if_.ElifBlocks { + elifBody := make([]ast2.Node, 0, len(elif.Body)) + for _, node := range elif.Body { + elifBody = append(elifBody, simplify.Node(node)) + } + newLastIf := &ast2.If{ + Condition: simplify.Expression(elif.Condition), + Body: elifBody, + Else: nil, + } + lastIf.Else = []ast2.Node{newLastIf} + lastIf = newLastIf + } + lastIf.Else = make([]ast2.Node, 0, len(if_.Else)) + for _, node := range if_.Else { + lastIf.Else = append(lastIf.Else, simplify.Node(node)) + } + return root +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-index.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-index.go new file mode 100644 index 0000000..20c27cf --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-index.go @@ -0,0 +1,13 @@ +package simplification + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/ast2" +) + +func (simplify *simplifyPass) Index(index *ast.IndexExpression) *ast2.Index { + return &ast2.Index{ + Source: simplify.Expression(index.Source), + Index: simplify.Expression(index.Index), + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-interface.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-interface.go new file mode 100644 index 0000000..3d93877 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-interface.go @@ -0,0 +1,22 @@ +package simplification + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/ast2" +) + +func (simplify *simplifyPass) Interface(i *ast.InterfaceStatement) *ast2.Class { + bases := make([]ast2.Expression, 0, len(i.Bases)) + for _, base := range i.Bases { + bases = append(bases, simplify.Expression(base)) + } + body := make([]ast2.Node, 0, len(i.MethodDefinitions)) + for _, methodDefinition := range i.MethodDefinitions { + body = append(body, simplify.Function(methodDefinition)) + } + return &ast2.Class{ + Name: simplify.Identifier(i.Name), + Bases: bases, + Body: body, + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-lambda.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-lambda.go new file mode 100644 index 0000000..4b5c4a6 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-lambda.go @@ -0,0 +1,17 @@ +package simplification + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/ast2" +) + +func (simplify *simplifyPass) Lambda(lambda *ast.LambdaExpression) *ast2.Lambda { + arguments := make([]*ast2.Identifier, 0, len(lambda.Arguments)) + for _, argument := range lambda.Arguments { + arguments = append(arguments, simplify.Identifier(argument)) + } + return &ast2.Lambda{ + Arguments: arguments, + Result: simplify.Expression(lambda.Code), + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-literal.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-literal.go new file mode 100644 index 0000000..6f3ed2f --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-literal.go @@ -0,0 +1,196 @@ +package simplification + +import ( + "fmt" + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/ast2" + "github.com/shoriwe/gplasma/pkg/lexer" + "strconv" + "strings" +) + +var directCharEscapeValue = map[rune][]rune{ + 'a': {7}, + 'b': {8}, + 'e': {'\\', 'e'}, + 'f': {12}, + 'n': {10}, + 'r': {13}, + 't': {9}, + '?': {'\\', '?'}, +} + +func (simplify *simplifyPass) simplifyInteger(s string) *ast2.Integer { + s = strings.ReplaceAll(strings.ToLower(s), "_", "") + value, parseError := strconv.ParseInt(s, 0, 64) + if parseError != nil { + panic(parseError) + } + return &ast2.Integer{ + Value: value, + } +} + +func (simplify *simplifyPass) simplifyFloat(s string) *ast2.Float { + s = strings.ReplaceAll(strings.ToLower(s), "_", "") + value, parseError := strconv.ParseFloat(s, 64) + if parseError != nil { + panic(parseError) + } + return &ast2.Float{ + Value: value, + } +} + +func hexCharToIntValue(c rune) int { + switch c { + case '0': + return 0 + case '1': + return 1 + case '2': + return 2 + case '3': + return 3 + case '4': + return 4 + case '5': + return 5 + case '6': + return 6 + case '7': + return 7 + case '8': + return 8 + case '9': + return 9 + case 'a', 'A': + return 10 + case 'b', 'B': + return 11 + case 'c', 'C': + return 12 + case 'd', 'D': + return 13 + case 'e', 'E': + return 14 + case 'f', 'F': + return 15 + } + panic("invalid hex") +} + +func (simplify *simplifyPass) simplifyString(rawS string) *ast2.String { + s := []rune(rawS) + s = s[1 : len(s)-1] + sLength := len(s) + escaped := false + resolved := make([]rune, 0, len(s)) + for index := 0; index < sLength; index++ { + char := s[index] + if escaped { + switch char { + case 'a', 'b', 'e', 'f', 'n', 'r', 't', '?': + // Replace char based + resolved = append(resolved, directCharEscapeValue[char]...) + case '\\', '\'', '"', '`': + // Replace escaped literals + resolved = append(resolved, char) + case 'x': + // Replace hex with numbers + index++ + a := hexCharToIntValue(s[index]) + index++ + b := hexCharToIntValue(s[index]) + resolved = append(resolved, rune(a*16+b)) + case 'u': + // Replace unicode with numbers + index++ + a := hexCharToIntValue(s[index]) + index++ + b := hexCharToIntValue(s[index]) + index++ + c := hexCharToIntValue(s[index]) + index++ + d := hexCharToIntValue(s[index]) + resolved = append(resolved, rune(a*4096+b*256+c*16+d)) + } + escaped = false + } else if char == '\\' { + escaped = true + } else { + resolved = append(resolved, char) + } + } + return &ast2.String{ + Contents: []byte(string(resolved)), + } +} + +func (simplify *simplifyPass) simplifyBytes(rawS string) *ast2.Bytes { + s := []rune(rawS) + s = s[2 : len(s)-1] + sLength := len(s) + escaped := false + resolved := make([]rune, 0, len(s)) + for index := 0; index < sLength; index++ { + char := s[index] + if escaped { + switch char { + case 'a', 'b', 'e', 'f', 'n', 'r', 't', '?': + // Replace char based + resolved = append(resolved, directCharEscapeValue[char]...) + case '\\', '\'', '"', '`': + // Replace escaped literals + resolved = append(resolved, char) + case 'x': + // Replace hex with numbers + index++ + a := s[index] + index++ + b := s[index] + resolved = append(resolved, a*16+b) + case 'u': + // Replace unicode with numbers + index++ + a := s[index] + index++ + b := s[index] + index++ + c := s[index] + index++ + d := s[index] + resolved = append(resolved, a*4096+b*256+c*16+d) + } + escaped = false + } else if char == '\\' { + escaped = true + } else { + resolved = append(resolved, char) + } + } + return &ast2.Bytes{ + Contents: []byte(string(resolved)), + } +} + +func (simplify *simplifyPass) Literal(literal *ast.BasicLiteralExpression) ast2.Expression { + switch literal.DirectValue { + case lexer.Integer, lexer.BinaryInteger, lexer.OctalInteger, lexer.HexadecimalInteger: + return simplify.simplifyInteger(literal.Token.String()) + case lexer.Float, lexer.ScientificFloat: + return simplify.simplifyFloat(literal.Token.String()) + case lexer.SingleQuoteString, lexer.DoubleQuoteString, lexer.CommandOutput: + return simplify.simplifyString(literal.Token.String()) + case lexer.True: + return &ast2.True{} + case lexer.False: + return &ast2.False{} + case lexer.None: + return &ast2.None{} + case lexer.ByteString: + return simplify.simplifyBytes(literal.Token.String()) + default: + panic(fmt.Sprintf("unknown literal %d", literal.DirectValue)) + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-loop-operations.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-loop-operations.go new file mode 100644 index 0000000..cde4410 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-loop-operations.go @@ -0,0 +1,14 @@ +package simplification + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/ast2" +) + +func (simplify *simplifyPass) Continue(c *ast.ContinueStatement) *ast2.Continue { + return &ast2.Continue{} +} + +func (simplify *simplifyPass) Break(c *ast.BreakStatement) *ast2.Break { + return &ast2.Break{} +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-module.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-module.go new file mode 100644 index 0000000..8cdb071 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-module.go @@ -0,0 +1,17 @@ +package simplification + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/ast2" +) + +func (simplify *simplifyPass) Module(module *ast.ModuleStatement) *ast2.Module { + body := make([]ast2.Node, 0, len(module.Body)) + for _, node := range module.Body { + body = append(body, simplify.Node(node)) + } + return &ast2.Module{ + Name: simplify.Identifier(module.Name), + Body: body, + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-parentheses.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-parentheses.go new file mode 100644 index 0000000..c659ced --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-parentheses.go @@ -0,0 +1,10 @@ +package simplification + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/ast2" +) + +func (simplify *simplifyPass) Parentheses(expression *ast.ParenthesesExpression) ast2.Expression { + return simplify.Expression(expression.X) +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-pass.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-pass.go new file mode 100644 index 0000000..1cf186d --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-pass.go @@ -0,0 +1,10 @@ +package simplification + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/ast2" +) + +func (simplify *simplifyPass) Pass(pass *ast.PassStatement) *ast2.Pass { + return &ast2.Pass{} +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-return-yield.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-return-yield.go new file mode 100644 index 0000000..b14fb55 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-return-yield.go @@ -0,0 +1,50 @@ +package simplification + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/ast2" +) + +func (simplify *simplifyPass) Return(ret *ast.ReturnStatement) *ast2.Return { + switch len(ret.Results) { + case 0: + return &ast2.Return{ + Result: &ast2.None{}, + } + case 1: + return &ast2.Return{ + Result: simplify.Expression(ret.Results[0]), + } + } + values := make([]ast2.Expression, 0, len(ret.Results)) + for _, result := range ret.Results { + values = append(values, simplify.Expression(result)) + } + return &ast2.Return{ + Result: &ast2.Tuple{ + Values: values, + }, + } +} + +func (simplify *simplifyPass) Yield(yield *ast.YieldStatement) *ast2.Yield { + switch len(yield.Results) { + case 0: + return &ast2.Yield{ + Result: &ast2.None{}, + } + case 1: + return &ast2.Yield{ + Result: simplify.Expression(yield.Results[0]), + } + } + values := make([]ast2.Expression, 0, len(yield.Results)) + for _, result := range yield.Results { + values = append(values, simplify.Expression(result)) + } + return &ast2.Yield{ + Result: &ast2.Tuple{ + Values: values, + }, + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-selector.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-selector.go new file mode 100644 index 0000000..52f3900 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-selector.go @@ -0,0 +1,13 @@ +package simplification + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/ast2" +) + +func (simplify *simplifyPass) Selector(selector *ast.SelectorExpression) *ast2.Selector { + return &ast2.Selector{ + X: simplify.Expression(selector.X), + Identifier: simplify.Identifier(selector.Identifier), + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-statement.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-statement.go new file mode 100644 index 0000000..4087686 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-statement.go @@ -0,0 +1,53 @@ +package simplification + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/ast2" +) + +func (simplify *simplifyPass) Statement(stmt ast.Statement) ast2.Statement { + switch s := stmt.(type) { + case *ast.AssignStatement: + return simplify.Assign(s) + case *ast.DoWhileStatement: + return simplify.DoWhile(s) + case *ast.WhileLoopStatement: + return simplify.While(s) + case *ast.UntilLoopStatement: + return simplify.Until(s) + case *ast.ForLoopStatement: + return simplify.For(s) + case *ast.IfStatement: + return simplify.If(s) + case *ast.UnlessStatement: + return simplify.Unless(s) + case *ast.SwitchStatement: + return simplify.Switch(s) + case *ast.ModuleStatement: + return simplify.Module(s) + case *ast.FunctionDefinitionStatement: + return simplify.Function(s) + case *ast.GeneratorDefinitionStatement: + return simplify.GeneratorDef(s) + case *ast.InterfaceStatement: + return simplify.Interface(s) + case *ast.ClassStatement: + return simplify.Class(s) + case *ast.ReturnStatement: + return simplify.Return(s) + case *ast.YieldStatement: + return simplify.Yield(s) + case *ast.ContinueStatement: + return simplify.Continue(s) + case *ast.BreakStatement: + return simplify.Break(s) + case *ast.PassStatement: + return simplify.Pass(s) + case *ast.DeleteStatement: + return simplify.Delete(s) + case *ast.DeferStatement: + return simplify.Defer(s) + default: + panic("unknown statement type") + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-super.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-super.go new file mode 100644 index 0000000..f7ebe98 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-super.go @@ -0,0 +1,12 @@ +package simplification + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/ast2" +) + +func (simplify *simplifyPass) Super(super *ast.SuperExpression) *ast2.Super { + return &ast2.Super{ + X: simplify.Expression(super.X), + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-switch.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-switch.go new file mode 100644 index 0000000..7c87ca7 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-switch.go @@ -0,0 +1,59 @@ +package simplification + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/ast2" +) + +func (simplify *simplifyPass) Switch(switch_ *ast.SwitchStatement) *ast2.If { + anonymousIdentifier := simplify.nextAnonIdentifier() + root := &ast2.If{ + SwitchSetup: &ast2.Assignment{ + Left: anonymousIdentifier, + Right: simplify.Expression(switch_.Target), + }, + Condition: nil, + Body: nil, + Else: nil, + } + currentIf := root + for caseIndex, case_ := range switch_.CaseBlocks { + for targetIndex, caseTarget := range case_.Cases { + if targetIndex == 0 { + currentIf.Condition = &ast2.Binary{ + Left: anonymousIdentifier, + Right: simplify.Expression(caseTarget), + Operator: ast2.Equals, + } + continue + } + currentIf.Condition = &ast2.Binary{ + Left: currentIf.Condition, + Right: &ast2.Binary{ + Left: anonymousIdentifier, + Right: simplify.Expression(caseTarget), + Operator: ast2.Equals, + }, + Operator: ast2.Or, + } + } + currentIf.Body = make([]ast2.Node, 0, len(case_.Body)) + for _, node := range case_.Body { + currentIf.Body = append(currentIf.Body, simplify.Node(node)) + } + if caseIndex+1 < len(switch_.CaseBlocks) { + newCurrentIf := &ast2.If{ + Condition: nil, + Body: nil, + Else: nil, + } + currentIf.Else = []ast2.Node{newCurrentIf} + currentIf = newCurrentIf + } + } + currentIf.Else = make([]ast2.Node, 0, len(switch_.Default)) + for _, node := range switch_.Default { + currentIf.Else = append(currentIf.Else, simplify.Node(node)) + } + return root +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-tuple.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-tuple.go new file mode 100644 index 0000000..de25b00 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-tuple.go @@ -0,0 +1,16 @@ +package simplification + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/ast2" +) + +func (simplify *simplifyPass) Tuple(tuple *ast.TupleExpression) *ast2.Tuple { + values := make([]ast2.Expression, 0, len(tuple.Values)) + for _, value := range tuple.Values { + values = append(values, simplify.Expression(value)) + } + return &ast2.Tuple{ + Values: values, + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-unary.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-unary.go new file mode 100644 index 0000000..14a216c --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-unary.go @@ -0,0 +1,25 @@ +package simplification + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/ast2" + "github.com/shoriwe/gplasma/pkg/lexer" +) + +func (simplify *simplifyPass) Unary(unary *ast.UnaryExpression) *ast2.Unary { + var operator ast2.UnaryOperator + switch unary.Operator.DirectValue { + case lexer.Not, lexer.SignNot: + operator = ast2.Not + case lexer.NegateBits: + operator = ast2.NegateBits + case lexer.Add: + operator = ast2.Positive + case lexer.Sub: + operator = ast2.Negative + } + return &ast2.Unary{ + Operator: operator, + X: simplify.Expression(unary.X), + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-unless.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-unless.go new file mode 100644 index 0000000..39ceccd --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-unless.go @@ -0,0 +1,43 @@ +package simplification + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/ast2" +) + +func (simplify *simplifyPass) Unless(unless *ast.UnlessStatement) *ast2.If { + body := make([]ast2.Node, 0, len(unless.Body)) + for _, node := range unless.Body { + body = append(body, simplify.Node(node)) + } + root := &ast2.If{ + Condition: &ast2.Unary{ + Operator: ast2.Not, + X: simplify.Expression(unless.Condition), + }, + Body: body, + Else: nil, + } + lastIf := root + for _, elif := range unless.ElifBlocks { + elifBody := make([]ast2.Node, 0, len(elif.Body)) + for _, node := range elif.Body { + elifBody = append(elifBody, simplify.Node(node)) + } + newLastIf := &ast2.If{ + Condition: &ast2.Unary{ + Operator: ast2.Not, + X: simplify.Expression(elif.Condition), + }, + Body: elifBody, + Else: nil, + } + lastIf.Else = []ast2.Node{newLastIf} + lastIf = newLastIf + } + lastIf.Else = make([]ast2.Node, 0, len(unless.Else)) + for _, node := range unless.Else { + lastIf.Else = append(lastIf.Else, simplify.Node(node)) + } + return root +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-until.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-until.go new file mode 100644 index 0000000..d867f87 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-until.go @@ -0,0 +1,23 @@ +package simplification + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/ast2" +) + +func (simplify *simplifyPass) Until(until *ast.UntilLoopStatement) *ast2.While { + var ( + body = make([]ast2.Node, 0, len(until.Body)) + condition ast2.Expression = &ast2.Unary{ + Operator: ast2.Not, + X: simplify.Expression(until.Condition), + } + ) + for _, node := range until.Body { + body = append(body, simplify.Node(node)) + } + return &ast2.While{ + Body: body, + Condition: condition, + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-while.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-while.go new file mode 100644 index 0000000..a1cb122 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify-while.go @@ -0,0 +1,20 @@ +package simplification + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/ast2" +) + +func (simplify *simplifyPass) While(while *ast.WhileLoopStatement) *ast2.While { + var ( + body = make([]ast2.Node, 0, len(while.Body)) + condition = simplify.Expression(while.Condition) + ) + for _, node := range while.Body { + body = append(body, simplify.Node(node)) + } + return &ast2.While{ + Body: body, + Condition: condition, + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify.go new file mode 100644 index 0000000..cac753e --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/simplification/simplify.go @@ -0,0 +1,64 @@ +package simplification + +import ( + "github.com/shoriwe/gplasma/pkg/ast" + "github.com/shoriwe/gplasma/pkg/ast2" +) + +type simplifyPass struct { + currentAnonIdent uint +} + +func (simplify *simplifyPass) Node(node ast.Node) ast2.Node { + switch n := node.(type) { + case ast.Statement: + return simplify.Statement(n) + case ast.Expression: + return simplify.Expression(n) + default: + panic("unknown node type") + } +} + +func Simplify(program *ast.Program) (ast2.Program, error) { + resultChan := make(chan ast2.Program, 1) + errorChan := make(chan error, 1) + go func(rChan chan ast2.Program, eChan chan error) { + defer func() { + err := recover() + if err != nil { + rChan <- nil + eChan <- err.(error) + } + }() + var ( + begin []ast2.Node + body []ast2.Node + end []ast2.Node + ) + simp := simplifyPass{currentAnonIdent: 1} + if program.Begin != nil { + begin = make([]ast2.Node, 0, len(program.Begin.Body)) + for _, node := range program.Begin.Body { + begin = append(begin, simp.Node(node)) + } + } + body = make([]ast2.Node, 0, len(program.Body)) + for _, node := range program.Body { + body = append(body, simp.Node(node)) + } + if program.End != nil { + end = make([]ast2.Node, 0, len(program.End.Body)) + for _, node := range program.End.Body { + end = append(end, simp.Node(node)) + } + } + result := make(ast2.Program, 0, len(begin)+len(body)+len(end)) + result = append(result, begin...) + result = append(result, body...) + result = append(result, end...) + resultChan <- result + errorChan <- nil + }(resultChan, errorChan) + return <-resultChan, <-errorChan +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/label.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/label.go new file mode 100644 index 0000000..efd1f05 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/label.go @@ -0,0 +1,23 @@ +package transformations_1 + +import ( + "fmt" + "github.com/shoriwe/gplasma/pkg/ast3" +) + +func (transform *transformPass) nextAnonIdentifier() *ast3.Identifier { + identifier := transform.currentIdentifier + transform.currentIdentifier++ + return &ast3.Identifier{ + Assignable: nil, + Symbol: fmt.Sprintf("_____transform_%d", identifier), + } +} + +func (transform *transformPass) nextLabel() *ast3.Label { + label := transform.currentLabel + transform.currentLabel++ + return &ast3.Label{ + Code: label, + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-array.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-array.go new file mode 100644 index 0000000..c6cd243 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-array.go @@ -0,0 +1,16 @@ +package transformations_1 + +import ( + "github.com/shoriwe/gplasma/pkg/ast2" + "github.com/shoriwe/gplasma/pkg/ast3" +) + +func (transform *transformPass) Array(array *ast2.Array) *ast3.Array { + values := make([]ast3.Expression, 0, len(array.Values)) + for _, value := range array.Values { + values = append(values, transform.Expression(value)) + } + return &ast3.Array{ + Values: values, + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-assignment.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-assignment.go new file mode 100644 index 0000000..109066d --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-assignment.go @@ -0,0 +1,14 @@ +package transformations_1 + +import ( + "github.com/shoriwe/gplasma/pkg/ast2" + "github.com/shoriwe/gplasma/pkg/ast3" +) + +func (transform *transformPass) Assignment(assignment *ast2.Assignment) []ast3.Node { + return []ast3.Node{&ast3.Assignment{ + Statement: nil, + Left: transform.Expression(assignment.Left).(ast3.Assignable), + Right: transform.Expression(assignment.Right), + }} +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-binary.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-binary.go new file mode 100644 index 0000000..6d49670 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-binary.go @@ -0,0 +1,93 @@ +package transformations_1 + +import ( + "fmt" + "github.com/shoriwe/gplasma/pkg/ast2" + "github.com/shoriwe/gplasma/pkg/ast3" + magic_functions "github.com/shoriwe/gplasma/pkg/common/magic-functions" +) + +func (transform *transformPass) Binary(binary *ast2.Binary) *ast3.Call { + var ( + function string + ) + switch binary.Operator { + case ast2.And: + function = magic_functions.And + case ast2.Or: + function = magic_functions.Or + case ast2.Xor: + function = magic_functions.Xor + case ast2.In: + return transform.Call( + &ast2.FunctionCall{ + Expression: nil, + Function: &ast2.Selector{ + Assignable: nil, + X: binary.Right, + Identifier: &ast2.Identifier{ + Assignable: nil, + Symbol: magic_functions.In, + }, + }, + Arguments: []ast2.Expression{binary.Left}, + }, + ) + case ast2.Is: + function = magic_functions.Is + case ast2.Implements: + function = magic_functions.Implements + case ast2.Equals: + function = magic_functions.Equal + case ast2.NotEqual: + function = magic_functions.NotEqual + case ast2.GreaterThan: + function = magic_functions.GreaterThan + case ast2.GreaterOrEqualThan: + function = magic_functions.GreaterOrEqualThan + case ast2.LessThan: + function = magic_functions.LessThan + case ast2.LessOrEqualThan: + function = magic_functions.LessOrEqualThan + case ast2.BitwiseOr: + function = magic_functions.BitwiseOr + case ast2.BitwiseXor: + function = magic_functions.BitwiseXor + case ast2.BitwiseAnd: + function = magic_functions.BitwiseAnd + case ast2.BitwiseLeft: + function = magic_functions.BitwiseLeft + case ast2.BitwiseRight: + function = magic_functions.BitwiseRight + case ast2.Add: + function = magic_functions.Add + case ast2.Sub: + function = magic_functions.Sub + case ast2.Mul: + function = magic_functions.Mul + case ast2.Div: + function = magic_functions.Div + case ast2.FloorDiv: + function = magic_functions.FloorDiv + case ast2.Modulus: + function = magic_functions.Modulus + case ast2.PowerOf: + function = magic_functions.PowerOf + default: + panic(fmt.Sprintf("unknown binary operator %d", binary.Operator)) + } + return transform.Call( + &ast2.FunctionCall{ + Expression: nil, + Function: &ast2.Selector{ + Assignable: nil, + X: binary.Left, + Identifier: &ast2.Identifier{ + Assignable: nil, + Symbol: function, + }, + }, + Arguments: []ast2.Expression{binary.Right}, + }, + ) +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-call.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-call.go new file mode 100644 index 0000000..ed9f796 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-call.go @@ -0,0 +1,17 @@ +package transformations_1 + +import ( + "github.com/shoriwe/gplasma/pkg/ast2" + "github.com/shoriwe/gplasma/pkg/ast3" +) + +func (transform *transformPass) Call(call *ast2.FunctionCall) *ast3.Call { + arguments := make([]ast3.Expression, 0, len(call.Arguments)) + for _, argument := range call.Arguments { + arguments = append(arguments, transform.Expression(argument)) + } + return &ast3.Call{ + Function: transform.Expression(call.Function), + Arguments: arguments, + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-class.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-class.go new file mode 100644 index 0000000..eaa3463 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-class.go @@ -0,0 +1,26 @@ +package transformations_1 + +import ( + "github.com/shoriwe/gplasma/pkg/ast2" + "github.com/shoriwe/gplasma/pkg/ast3" +) + +func (transform *transformPass) Class(class *ast2.Class) []ast3.Node { + body := make([]ast3.Node, len(class.Body)) + for _, node := range class.Body { + body = append(body, transform.Node(node)...) + } + bases := make([]ast3.Expression, 0, len(class.Bases)) + for _, base := range class.Bases { + bases = append(bases, transform.Expression(base)) + } + return []ast3.Node{ + &ast3.Assignment{ + Left: transform.Identifier(class.Name), + Right: &ast3.Class{ + Bases: bases, + Body: body, + }, + }, + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-defer.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-defer.go new file mode 100644 index 0000000..3810c80 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-defer.go @@ -0,0 +1,14 @@ +package transformations_1 + +import ( + "github.com/shoriwe/gplasma/pkg/ast2" + "github.com/shoriwe/gplasma/pkg/ast3" +) + +func (transform *transformPass) Defer(def *ast2.Defer) []ast3.Node { + return []ast3.Node{ + &ast3.Defer{ + X: transform.Expression(def.X), + }, + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-delete.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-delete.go new file mode 100644 index 0000000..caa1bcd --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-delete.go @@ -0,0 +1,14 @@ +package transformations_1 + +import ( + "github.com/shoriwe/gplasma/pkg/ast2" + "github.com/shoriwe/gplasma/pkg/ast3" +) + +func (transform *transformPass) Delete(del *ast2.Delete) []ast3.Node { + return []ast3.Node{ + &ast3.Delete{ + X: transform.Expression(del.X).(ast3.Assignable), + }, + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-do-while.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-do-while.go new file mode 100644 index 0000000..294f7e7 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-do-while.go @@ -0,0 +1,36 @@ +package transformations_1 + +import ( + "github.com/shoriwe/gplasma/pkg/ast2" + "github.com/shoriwe/gplasma/pkg/ast3" +) + +func (transform *transformPass) DoWhile(doWhile *ast2.DoWhile) []ast3.Node { + startLabel := transform.nextLabel() + endLabel := transform.nextLabel() + condition := &ast3.IfJump{ + Condition: transform.Expression(doWhile.Condition), + Target: startLabel, + } + body := make([]ast3.Node, 0, len(doWhile.Body)) + for _, node := range doWhile.Body { + body = append(body, transform.Node(node)...) + } + for _, node := range body { + switch n := node.(type) { + case *ast3.ContinueJump: + if n.Target == nil { + n.Target = startLabel + } + case *ast3.BreakJump: + if n.Target == nil { + n.Target = endLabel + } + } + } + result := make([]ast3.Node, 0, 3+len(body)) + result = append(result, startLabel) + result = append(result, body...) + result = append(result, condition, endLabel) + return result +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-expression.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-expression.go new file mode 100644 index 0000000..ed146f7 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-expression.go @@ -0,0 +1,55 @@ +package transformations_1 + +import ( + "fmt" + "github.com/shoriwe/gplasma/pkg/ast2" + "github.com/shoriwe/gplasma/pkg/ast3" + "reflect" +) + +func (transform *transformPass) Expression(expr ast2.Expression) ast3.Expression { + switch e := expr.(type) { + case *ast2.Binary: + return transform.Binary(e) + case *ast2.Unary: + return transform.Unary(e) + case *ast2.IfOneLiner: + return transform.IfOneLiner(e) + case *ast2.Array: + return transform.Array(e) + case *ast2.Tuple: + return transform.Tuple(e) + case *ast2.Hash: + return transform.Hash(e) + case *ast2.Identifier: + return transform.Identifier(e) + case *ast2.Integer: + return transform.Integer(e) + case *ast2.Float: + return transform.Float(e) + case *ast2.String: + return transform.String(e) + case *ast2.Bytes: + return transform.Bytes(e) + case *ast2.True: + return transform.True(e) + case *ast2.False: + return transform.False(e) + case *ast2.None: + return transform.None(e) + case *ast2.Lambda: + return transform.Lambda(e) + case *ast2.Generator: + return transform.GeneratorExpr(e) + case *ast2.Selector: + return transform.Selector(e) + case *ast2.FunctionCall: + return transform.Call(e) + case *ast2.Index: + return transform.Index(e) + case *ast2.Super: + return transform.Super(e) + default: + panic(fmt.Sprintf("unknown expression type %s", reflect.TypeOf(e).String())) + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-function.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-function.go new file mode 100644 index 0000000..05e0581 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-function.go @@ -0,0 +1,24 @@ +package transformations_1 + +import ( + "github.com/shoriwe/gplasma/pkg/ast2" + "github.com/shoriwe/gplasma/pkg/ast3" +) + +func (transform *transformPass) Function(function *ast2.FunctionDefinition) []ast3.Node { + arguments := make([]*ast3.Identifier, 0, len(function.Arguments)) + for _, argument := range function.Arguments { + arguments = append(arguments, transform.Identifier(argument)) + } + body := make([]ast3.Node, 0, len(function.Body)) + for _, node := range function.Body { + body = append(body, transform.Node(node)...) + } + return []ast3.Node{&ast3.Assignment{ + Left: transform.Identifier(function.Name), + Right: &ast3.Function{ + Arguments: arguments, + Body: body, + }, + }} +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-generator-expr.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-generator-expr.go new file mode 100644 index 0000000..f637c00 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-generator-expr.go @@ -0,0 +1,121 @@ +package transformations_1 + +import ( + "github.com/shoriwe/gplasma/pkg/ast2" + "github.com/shoriwe/gplasma/pkg/ast3" + magic_functions "github.com/shoriwe/gplasma/pkg/common/magic-functions" + special_symbols "github.com/shoriwe/gplasma/pkg/common/special-symbols" +) + +func (transform *transformPass) GeneratorExpr(generator *ast2.Generator) *ast3.Call { + selfSource := &ast3.Selector{ + X: &ast3.Identifier{ + Symbol: special_symbols.Self, + }, + Identifier: &ast3.Identifier{ + Symbol: "_____source", + }, + } + initSourceArgument := &ast3.Identifier{ + Symbol: "__source__", + } + initFunction := &ast3.Assignment{ + Left: &ast3.Identifier{ + Symbol: magic_functions.Init, + }, + Right: &ast3.Function{ + Arguments: []*ast3.Identifier{initSourceArgument}, + Body: []ast3.Node{ + &ast3.Assignment{ + Left: selfSource, + Right: &ast3.Call{ + Function: &ast3.Selector{ + X: initSourceArgument, + Identifier: &ast3.Identifier{ + Symbol: magic_functions.Iter, + }, + }, + }, + }, + }, + }, + } + hasNextFunction := &ast3.Assignment{ + Left: &ast3.Identifier{ + Symbol: magic_functions.HasNext, + }, + Right: &ast3.Function{ + Body: []ast3.Node{ + &ast3.Return{ + Result: &ast3.Call{ + Function: &ast3.Selector{ + X: selfSource, + Identifier: &ast3.Identifier{ + Symbol: magic_functions.HasNext, + }, + }, + }, + }, + }, + }, + } + anonReceiver := transform.nextAnonIdentifier() + sourceNext := &ast3.Assignment{ + Left: anonReceiver, + Right: &ast3.Call{ + Function: &ast3.Selector{ + X: selfSource, + Identifier: &ast3.Identifier{ + Symbol: magic_functions.Next, + }, + }, + }, + } + expand := make([]ast3.Node, 0, len(generator.Receivers)) + if len(generator.Receivers) > 1 { + for index, receiver := range generator.Receivers { + expand = append(expand, &ast3.Assignment{ + Left: transform.Identifier(receiver), + Right: &ast3.Index{ + Source: anonReceiver, + Index: &ast3.Integer{ + Value: int64(index), + }, + }, + }) + } + } else { + expand = append(expand, &ast3.Assignment{ + Left: &ast3.Identifier{ + Symbol: generator.Receivers[0].Symbol, + }, + Right: anonReceiver, + }) + } + result := &ast3.Return{ + Statement: nil, + Result: transform.Expression(generator.Operation), + } + nextBody := make([]ast3.Node, 0, 2+len(expand)) + nextBody = append(nextBody, sourceNext) + nextBody = append(nextBody, expand...) + nextBody = append(nextBody, result) + nextFunction := &ast3.Assignment{ + Left: &ast3.Identifier{ + Symbol: magic_functions.Next, + }, + Right: &ast3.Function{ + Body: nextBody, + }, + } + class := &ast3.Class{ + Expression: nil, + Bases: nil, + Body: []ast3.Node{initFunction, hasNextFunction, nextFunction}, + } + sourceExpr := transform.Expression(generator.Source) + return &ast3.Call{ + Function: class, + Arguments: []ast3.Expression{sourceExpr}, + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-generator.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-generator.go new file mode 100644 index 0000000..853d91f --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-generator.go @@ -0,0 +1,429 @@ +package transformations_1 + +import ( + "fmt" + "github.com/shoriwe/gplasma/pkg/ast2" + "github.com/shoriwe/gplasma/pkg/ast3" + "github.com/shoriwe/gplasma/pkg/common" + "github.com/shoriwe/gplasma/pkg/common/magic-functions" + "github.com/shoriwe/gplasma/pkg/common/special-symbols" + "reflect" +) + +func getRoot(expr ast3.Expression) ast3.Expression { + current := expr + for { + switch c := current.(type) { + case *ast3.Selector: + current = c.X + case *ast3.Index: + current = c.Source + default: + return c + } + } +} + +type generatorTransform struct { + transform *transformPass + selfSymbols map[string]struct{} + hasNextVariable *ast3.Selector + labelsOrder []*ast3.Selector + labels map[*ast3.Selector]*ast3.Label +} + +func newGeneratorTransform(transform *transformPass) *generatorTransform { + return &generatorTransform{ + transform: transform, + selfSymbols: map[string]struct{}{}, + hasNextVariable: &ast3.Selector{ + X: &ast3.Identifier{ + Symbol: special_symbols.Self, + }, + Identifier: &ast3.Identifier{ + Symbol: "____has_next", + }, + }, + labelsOrder: nil, + labels: map[*ast3.Selector]*ast3.Label{}, + } +} + +func (gt *generatorTransform) nextLabelIdentifier() (*ast3.Label, *ast3.Selector) { + label := gt.transform.nextLabel() + return label, &ast3.Selector{ + X: &ast3.Identifier{ + Symbol: special_symbols.Self, + }, + Identifier: &ast3.Identifier{ + Symbol: fmt.Sprintf("_______label_%d", label.Code), + }, + } +} + +/* + - Transform assignments to self.IDENTIFIER + - Update Identifier access to self.IDENTIFIER + - Add update jump condition variable before yield + - Add label after yield + - Update to has_next variable before return +*/ +func (gt *generatorTransform) resolve(node ast3.Node, symbols map[string]struct{}) []ast3.Node { + symbolsCopy := common.CopyMap(symbols) + switch n := node.(type) { + case *ast3.Assignment: + if ident, ok := n.Left.(*ast3.Identifier); ok { + _, found := gt.selfSymbols[ident.Symbol] + if found { + delete(symbolsCopy, ident.Symbol) + } + } + return []ast3.Node{&ast3.Assignment{ + Left: gt.resolve(n.Left, symbolsCopy)[0].(ast3.Assignable), + Right: gt.resolve(n.Right, symbolsCopy)[0].(ast3.Expression), + }} + case *ast3.Label: + return []ast3.Node{n} + case *ast3.Jump: + return []ast3.Node{n} + case *ast3.ContinueJump: + return []ast3.Node{n} + case *ast3.BreakJump: + return []ast3.Node{n} + case *ast3.IfJump: + return []ast3.Node{&ast3.IfJump{ + Condition: gt.resolve(n.Condition, symbolsCopy)[0].(ast3.Expression), + Target: n.Target, + }} + case *ast3.Return: + return []ast3.Node{ + &ast3.Assignment{ + Left: gt.hasNextVariable, + Right: &ast3.False{}, + }, + &ast3.Return{ + Result: gt.resolve(n.Result, symbolsCopy)[0].(ast3.Expression), + }, + } + case *ast3.Yield: + label, selector := gt.nextLabelIdentifier() + gt.labels[selector] = label + gt.labelsOrder = append(gt.labelsOrder, selector) + return []ast3.Node{ + &ast3.Assignment{ + Left: selector, + Right: &ast3.True{}, + }, + &ast3.Yield{ + Result: gt.resolve(n.Result, symbolsCopy)[0].(ast3.Expression), + }, + label, + } + case *ast3.Delete: + return []ast3.Node{&ast3.Delete{ + Statement: nil, + X: gt.resolve(n.X, symbolsCopy)[0].(ast3.Assignable), + }} + case *ast3.Defer: + return []ast3.Node{&ast3.Defer{ + Statement: nil, + X: gt.resolve(n.X, symbolsCopy)[0].(ast3.Expression), + }} + case *ast3.Function: + for _, argument := range n.Arguments { + if _, found := symbolsCopy[argument.Symbol]; found { + delete(symbolsCopy, argument.Symbol) + } + } + body := make([]ast3.Node, 0, len(n.Body)) + for _, child := range n.Body { + body = append(body, gt.resolve(child, symbolsCopy)...) + } + return []ast3.Node{&ast3.Function{ + Arguments: n.Arguments, + Body: body, + }} + case *ast3.Class: + bases := make([]ast3.Expression, 0, len(n.Bases)) + for _, base := range n.Bases { + bases = append(bases, gt.resolve(base, symbolsCopy)[0].(ast3.Expression)) + } + body := make([]ast3.Node, 0, len(n.Body)) + for _, child := range n.Body { + body = append(body, gt.resolve(child, symbolsCopy)...) + } + return []ast3.Node{&ast3.Class{ + Bases: bases, + Body: body, + }} + case *ast3.Call: + arguments := make([]ast3.Expression, 0, len(n.Arguments)) + for _, argument := range n.Arguments { + arguments = append(arguments, gt.resolve(argument, symbolsCopy)[0].(ast3.Expression)) + } + return []ast3.Node{&ast3.Call{ + Function: gt.resolve(n.Function, symbolsCopy)[0].(ast3.Expression), + Arguments: arguments, + }} + case *ast3.Array: + values := make([]ast3.Expression, 0, len(n.Values)) + for _, value := range n.Values { + values = append(values, gt.resolve(value, symbolsCopy)[0].(ast3.Expression)) + } + return []ast3.Node{&ast3.Array{ + Values: values, + }} + case *ast3.Tuple: + values := make([]ast3.Expression, 0, len(n.Values)) + for _, value := range n.Values { + values = append(values, gt.resolve(value, symbolsCopy)[0].(ast3.Expression)) + } + return []ast3.Node{&ast3.Tuple{ + Values: values, + }} + case *ast3.Hash: + values := make([]*ast3.KeyValue, 0, len(n.Values)) + for _, keyValue := range n.Values { + values = append(values, &ast3.KeyValue{ + Key: gt.resolve(keyValue.Key, symbolsCopy)[0].(ast3.Expression), + Value: gt.resolve(keyValue.Value, symbolsCopy)[0].(ast3.Expression), + }) + } + return []ast3.Node{&ast3.Hash{ + Values: values, + }} + case *ast3.Identifier: + if _, found := symbolsCopy[n.Symbol]; found { + return []ast3.Node{&ast3.Selector{ + X: &ast3.Identifier{ + Symbol: special_symbols.Self, + }, + Identifier: n, + }} + } + return []ast3.Node{n} + case *ast3.Integer: + return []ast3.Node{n} + case *ast3.Float: + return []ast3.Node{n} + case *ast3.String: + return []ast3.Node{n} + case *ast3.Bytes: + return []ast3.Node{n} + case *ast3.True: + return []ast3.Node{n} + case *ast3.False: + return []ast3.Node{n} + case *ast3.None: + return []ast3.Node{n} + case *ast3.Selector: + return []ast3.Node{&ast3.Selector{ + X: gt.resolve(n.X, symbolsCopy)[0].(ast3.Expression), + Identifier: n.Identifier, + }} + case *ast3.Index: + return []ast3.Node{&ast3.Index{ + Source: gt.resolve(n.Source, symbolsCopy)[0].(ast3.Expression), + Index: gt.resolve(n.Index, symbolsCopy)[0].(ast3.Expression), + }} + case *ast3.Super: + return []ast3.Node{&ast3.Super{ + X: gt.resolve(n.X, symbolsCopy)[0].(ast3.Expression), + }} + default: + panic(fmt.Sprintf("unknown node type %s", reflect.TypeOf(node).String())) + } +} + +// Enumerate self symbols +func (gt *generatorTransform) enumerate(a ast3.Assignable) { + switch left := a.(type) { + case *ast3.Identifier: + gt.selfSymbols[left.Symbol] = struct{}{} + case *ast3.Selector: + root := getRoot(left.X) + ident, isIdent := root.(*ast3.Identifier) + if !isIdent { + return + } + if _, found := gt.selfSymbols[ident.Symbol]; !found { + return + } + gt.selfSymbols[ident.Symbol] = struct{}{} + case *ast3.Index: + root := getRoot(left.Source) + ident, isIdent := root.(*ast3.Identifier) + if !isIdent { + return + } + if _, found := gt.selfSymbols[ident.Symbol]; !found { + return + } + gt.selfSymbols[ident.Symbol] = struct{}{} + default: + panic(fmt.Sprintf("unknown assignable type %s", reflect.TypeOf(a).String())) + } +} + +func (gt *generatorTransform) process(node ast3.Node) []ast3.Node { + switch n := node.(type) { + case *ast3.Assignment: + gt.enumerate(n.Left) + return []ast3.Node{&ast3.Assignment{ + Left: gt.resolve(n.Left, gt.selfSymbols)[0].(ast3.Assignable), + Right: gt.resolve(n.Right, gt.selfSymbols)[0].(ast3.Expression), + }} + default: + return gt.resolve(n, gt.selfSymbols) + } +} + +/* + - Prepend has_next jump + - Prepend jump table + - Append Body + - Append On finish label + - Append Return none +*/ +func (gt *generatorTransform) setup(body []ast3.Node) []ast3.Node { + result := make([]ast3.Node, 0, 3+len(gt.labelsOrder)+len(body)) + onFinishLabel := gt.transform.nextLabel() + // Has next jump + result = append(result, &ast3.IfJump{ + Condition: &ast3.Call{ + Function: &ast3.Selector{ + Assignable: nil, + X: gt.hasNextVariable, + Identifier: &ast3.Identifier{ + Symbol: magic_functions.Not, + }, + }, + }, + Target: onFinishLabel, + }) + // Jump table + for _, selector := range gt.labelsOrder { + label := gt.labels[selector] + result = append(result, &ast3.IfJump{ + Statement: nil, + Condition: selector, + Target: label, + }) + } + // Body + for _, node := range body { + result = append(result, node) + } + // Finish label + result = append(result, onFinishLabel) + // Return none + result = append(result, &ast3.Return{ + Result: &ast3.None{}, + }) + return result +} + +func (gt *generatorTransform) next(rawBody []ast3.Node) *ast3.Assignment { + body := make([]ast3.Node, 0, len(rawBody)) + for _, node := range rawBody { + body = append(body, gt.process(node)...) + } + return &ast3.Assignment{ + Left: &ast3.Identifier{ + Symbol: magic_functions.Next, + }, + Right: &ast3.Function{ + Body: gt.setup(body), + }, + } +} + +func (gt *generatorTransform) hasNext() *ast3.Assignment { + body := []ast3.Node{ + &ast3.Return{ + Result: gt.hasNextVariable, + }, + } + return &ast3.Assignment{ + Statement: nil, + Left: &ast3.Identifier{ + Symbol: magic_functions.HasNext, + }, + Right: &ast3.Function{ + Body: body, + }, + } +} + +func (gt *generatorTransform) init(arguments []*ast3.Identifier) *ast3.Assignment { + body := make([]ast3.Node, 0, len(arguments)) + for _, argument := range arguments { + gt.selfSymbols[argument.Symbol] = struct{}{} + body = append(body, &ast3.Assignment{ + Left: &ast3.Selector{ + Assignable: nil, + X: &ast3.Identifier{ + Symbol: special_symbols.Self, + }, + Identifier: argument, + }, + Right: argument, + }) + } + return &ast3.Assignment{ + Left: &ast3.Identifier{ + Symbol: magic_functions.Init, + }, + Right: &ast3.Function{ + Arguments: arguments, + Body: body, + }, + } +} + +func (gt *generatorTransform) class(rawFunctionBody []ast3.Node, arguments []*ast3.Identifier) *ast3.Class { + initFunction := gt.init(arguments) + nextFunction := gt.next(rawFunctionBody) + hasNextFunction := gt.hasNext() + body := make([]ast3.Node, 0, 3+len(gt.selfSymbols)) + body = append(body, &ast3.Assignment{ + Left: gt.hasNextVariable, + Right: &ast3.True{}, + }) + for selfSymbol := range gt.selfSymbols { + body = append(body, &ast3.Assignment{ + Left: &ast3.Identifier{ + Symbol: selfSymbol, + }, + Right: &ast3.None{}, + }) + } + body = append(body, initFunction, hasNextFunction, nextFunction) + for selector := range gt.labels { + body = append(body, &ast3.Assignment{ + Statement: nil, + Left: selector.Identifier, + Right: &ast3.False{}, + }) + } + return &ast3.Class{ + Body: body, + } +} + +func (transform *transformPass) GeneratorDef(generator *ast2.GeneratorDefinition) []ast3.Node { + rawNextFunctionBody := make([]ast3.Node, 0, len(generator.Body)) + for _, node := range generator.Body { + rawNextFunctionBody = append(rawNextFunctionBody, transform.Node(node)...) + } + arguments := make([]*ast3.Identifier, 0, len(generator.Arguments)) + for _, argument := range generator.Arguments { + arguments = append(arguments, transform.Identifier(argument)) + } + class := newGeneratorTransform(transform).class(rawNextFunctionBody, arguments) + return []ast3.Node{&ast3.Assignment{ + Statement: nil, + Left: transform.Identifier(generator.Name), + Right: class, + }} +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-hash.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-hash.go new file mode 100644 index 0000000..e9075b3 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-hash.go @@ -0,0 +1,19 @@ +package transformations_1 + +import ( + "github.com/shoriwe/gplasma/pkg/ast2" + "github.com/shoriwe/gplasma/pkg/ast3" +) + +func (transform *transformPass) Hash(hash *ast2.Hash) *ast3.Hash { + values := make([]*ast3.KeyValue, 0, len(hash.Values)) + for _, keyValue := range hash.Values { + values = append(values, &ast3.KeyValue{ + Key: transform.Expression(keyValue.Key), + Value: transform.Expression(keyValue.Value), + }) + } + return &ast3.Hash{ + Values: values, + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-identifier.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-identifier.go new file mode 100644 index 0000000..c64a6bc --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-identifier.go @@ -0,0 +1,12 @@ +package transformations_1 + +import ( + "github.com/shoriwe/gplasma/pkg/ast2" + "github.com/shoriwe/gplasma/pkg/ast3" +) + +func (transform *transformPass) Identifier(ident *ast2.Identifier) *ast3.Identifier { + return &ast3.Identifier{ + Symbol: ident.Symbol, + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-if-one-liner.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-if-one-liner.go new file mode 100644 index 0000000..f710700 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-if-one-liner.go @@ -0,0 +1,35 @@ +package transformations_1 + +import ( + "github.com/shoriwe/gplasma/pkg/ast2" + "github.com/shoriwe/gplasma/pkg/ast3" +) + +func (transform *transformPass) IfOneLiner(iol *ast2.IfOneLiner) *ast3.Call { + end := transform.nextLabel() + elseLabel := transform.nextLabel() + condition := &ast3.IfJump{ + Condition: transform.Expression(&ast2.Unary{ + Operator: ast2.Not, + X: iol.Condition, + }), + Target: elseLabel, + } + result := transform.Expression(iol.Result) + endJump := &ast3.Jump{ + Target: end, + } + else_ := transform.Expression(iol.Else) + var body []ast3.Node + body = append(body, condition) + body = append(body, result) + body = append(body, endJump) + body = append(body, elseLabel) + body = append(body, else_) + body = append(body, end) + return &ast3.Call{ + Function: &ast3.Function{ + Body: body, + }, + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-if.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-if.go new file mode 100644 index 0000000..531884b --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-if.go @@ -0,0 +1,46 @@ +package transformations_1 + +import ( + "github.com/shoriwe/gplasma/pkg/ast2" + "github.com/shoriwe/gplasma/pkg/ast3" +) + +func (transform *transformPass) If(if_ *ast2.If) []ast3.Node { + elseLabel := transform.nextLabel() + endLabel := transform.nextLabel() + condition := &ast3.IfJump{ + Condition: transform.Expression(&ast2.Unary{ + Operator: ast2.Not, + X: if_.Condition, + }), + Target: elseLabel, + } + // Switch setup + var switchSetup []ast3.Node + if if_.SwitchSetup != nil { + switchSetup = transform.Assignment(if_.SwitchSetup) + } + // If + ifBody := make([]ast3.Node, 0, 1+len(if_.Body)) + for _, node := range if_.Body { + ifBody = append(ifBody, transform.Node(node)...) + } + ifBody = append(ifBody, &ast3.Jump{Target: endLabel}) + // Else + elseBody := make([]ast3.Node, 0, 2+len(if_.Else)) + elseBody = append(elseBody, elseLabel) + for _, node := range if_.Else { + elseBody = append(elseBody, transform.Node(node)...) + } + elseBody = append(elseBody, &ast3.Jump{Target: endLabel}) + // + result := make([]ast3.Node, 0, 3+len(ifBody)+len(elseBody)) + if switchSetup != nil { + result = append(result, switchSetup...) + } + result = append(result, condition) + result = append(result, ifBody...) + result = append(result, elseBody...) + result = append(result, endLabel) + return result +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-index.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-index.go new file mode 100644 index 0000000..998aac9 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-index.go @@ -0,0 +1,13 @@ +package transformations_1 + +import ( + "github.com/shoriwe/gplasma/pkg/ast2" + "github.com/shoriwe/gplasma/pkg/ast3" +) + +func (transform *transformPass) Index(index *ast2.Index) *ast3.Index { + return &ast3.Index{ + Source: transform.Expression(index.Source), + Index: transform.Expression(index.Index), + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-lambda.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-lambda.go new file mode 100644 index 0000000..943dee8 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-lambda.go @@ -0,0 +1,23 @@ +package transformations_1 + +import ( + "github.com/shoriwe/gplasma/pkg/ast2" + "github.com/shoriwe/gplasma/pkg/ast3" +) + +func (transform *transformPass) Lambda(lambda *ast2.Lambda) *ast3.Function { + arguments := make([]*ast3.Identifier, 0, len(lambda.Arguments)) + for _, argument := range lambda.Arguments { + arguments = append(arguments, transform.Identifier(argument)) + } + return &ast3.Function{ + Expression: nil, + Arguments: arguments, + Body: []ast3.Node{ + &ast3.Return{ + Statement: nil, + Result: transform.Expression(lambda.Result), + }, + }, + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-literals.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-literals.go new file mode 100644 index 0000000..5f0d449 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-literals.go @@ -0,0 +1,42 @@ +package transformations_1 + +import ( + "github.com/shoriwe/gplasma/pkg/ast2" + "github.com/shoriwe/gplasma/pkg/ast3" +) + +func (transform *transformPass) Integer(integer *ast2.Integer) *ast3.Integer { + return &ast3.Integer{ + Value: integer.Value, + } +} + +func (transform *transformPass) Float(float *ast2.Float) *ast3.Float { + return &ast3.Float{ + Value: float.Value, + } +} + +func (transform *transformPass) String(s *ast2.String) *ast3.String { + return &ast3.String{ + Contents: s.Contents, + } +} + +func (transform *transformPass) Bytes(bytes *ast2.Bytes) *ast3.Bytes { + return &ast3.Bytes{ + Contents: bytes.Contents, + } +} + +func (transform *transformPass) True(t *ast2.True) *ast3.True { + return &ast3.True{} +} + +func (transform *transformPass) False(t *ast2.False) *ast3.False { + return &ast3.False{} +} + +func (transform *transformPass) None(t *ast2.None) *ast3.None { + return &ast3.None{} +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-loop-operations.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-loop-operations.go new file mode 100644 index 0000000..7cfca03 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-loop-operations.go @@ -0,0 +1,18 @@ +package transformations_1 + +import ( + "github.com/shoriwe/gplasma/pkg/ast2" + "github.com/shoriwe/gplasma/pkg/ast3" +) + +func (transform *transformPass) Continue(c *ast2.Continue) []ast3.Node { + return []ast3.Node{&ast3.ContinueJump{}} +} + +func (transform *transformPass) Break(b *ast2.Break) []ast3.Node { + return []ast3.Node{&ast3.BreakJump{}} +} + +func (transform *transformPass) Pass(p *ast2.Pass) []ast3.Node { + return nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-module.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-module.go new file mode 100644 index 0000000..3a07849 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-module.go @@ -0,0 +1,29 @@ +package transformations_1 + +import ( + "github.com/shoriwe/gplasma/pkg/ast2" + "github.com/shoriwe/gplasma/pkg/ast3" + magic_functions "github.com/shoriwe/gplasma/pkg/common/magic-functions" +) + +func (transform *transformPass) Module(module *ast2.Module) []ast3.Node { + body := make([]ast3.Node, 0, len(module.Body)) + for _, node := range module.Body { + body = append(body, transform.Node(node)...) + } + body = append(body, &ast3.Assignment{ + Left: &ast3.Identifier{ + Symbol: magic_functions.Init, + }, + Right: &ast3.Function{}, + }) + moduleAssignment := &ast3.Assignment{ + Left: transform.Identifier(module.Name), + Right: &ast3.Call{ + Function: &ast3.Class{ + Body: body, + }, + }, + } + return []ast3.Node{moduleAssignment} +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-return-yield.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-return-yield.go new file mode 100644 index 0000000..b259b30 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-return-yield.go @@ -0,0 +1,18 @@ +package transformations_1 + +import ( + "github.com/shoriwe/gplasma/pkg/ast2" + "github.com/shoriwe/gplasma/pkg/ast3" +) + +func (transform *transformPass) Yield(yield *ast2.Yield) []ast3.Node { + return []ast3.Node{&ast3.Yield{ + Result: transform.Expression(yield.Result), + }} +} + +func (transform *transformPass) Return(ret *ast2.Return) []ast3.Node { + return []ast3.Node{&ast3.Return{ + Result: transform.Expression(ret.Result), + }} +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-selector.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-selector.go new file mode 100644 index 0000000..17875c5 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-selector.go @@ -0,0 +1,13 @@ +package transformations_1 + +import ( + "github.com/shoriwe/gplasma/pkg/ast2" + "github.com/shoriwe/gplasma/pkg/ast3" +) + +func (transform *transformPass) Selector(selector *ast2.Selector) *ast3.Selector { + return &ast3.Selector{ + X: transform.Expression(selector.X), + Identifier: transform.Identifier(selector.Identifier), + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-statement.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-statement.go new file mode 100644 index 0000000..eb43ff3 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-statement.go @@ -0,0 +1,45 @@ +package transformations_1 + +import ( + "fmt" + "github.com/shoriwe/gplasma/pkg/ast2" + "github.com/shoriwe/gplasma/pkg/ast3" + "reflect" +) + +func (transform *transformPass) Statement(stmt ast2.Statement) []ast3.Node { + switch s := stmt.(type) { + case *ast2.Assignment: + return transform.Assignment(s) + case *ast2.DoWhile: + return transform.DoWhile(s) + case *ast2.While: + return transform.While(s) + case *ast2.If: + return transform.If(s) + case *ast2.Module: + return transform.Module(s) + case *ast2.FunctionDefinition: + return transform.Function(s) + case *ast2.GeneratorDefinition: + return transform.GeneratorDef(s) + case *ast2.Class: + return transform.Class(s) + case *ast2.Return: + return transform.Return(s) + case *ast2.Yield: + return transform.Yield(s) + case *ast2.Continue: + return transform.Continue(s) + case *ast2.Break: + return transform.Break(s) + case *ast2.Pass: + return transform.Pass(s) + case *ast2.Delete: + return transform.Delete(s) + case *ast2.Defer: + return transform.Defer(s) + default: + panic(fmt.Sprintf("unknown statement type %s", reflect.TypeOf(s).String())) + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-super.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-super.go new file mode 100644 index 0000000..ae58401 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-super.go @@ -0,0 +1,12 @@ +package transformations_1 + +import ( + "github.com/shoriwe/gplasma/pkg/ast2" + "github.com/shoriwe/gplasma/pkg/ast3" +) + +func (transform *transformPass) Super(super *ast2.Super) *ast3.Super { + return &ast3.Super{ + X: transform.Expression(super.X), + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-tuple.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-tuple.go new file mode 100644 index 0000000..34b6bda --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-tuple.go @@ -0,0 +1,16 @@ +package transformations_1 + +import ( + "github.com/shoriwe/gplasma/pkg/ast2" + "github.com/shoriwe/gplasma/pkg/ast3" +) + +func (transform *transformPass) Tuple(tuple *ast2.Tuple) *ast3.Tuple { + values := make([]ast3.Expression, 0, len(tuple.Values)) + for _, value := range tuple.Values { + values = append(values, transform.Expression(value)) + } + return &ast3.Tuple{ + Values: values, + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-unary.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-unary.go new file mode 100644 index 0000000..c4ebeff --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-unary.go @@ -0,0 +1,36 @@ +package transformations_1 + +import ( + "fmt" + "github.com/shoriwe/gplasma/pkg/ast2" + "github.com/shoriwe/gplasma/pkg/ast3" + magic_functions "github.com/shoriwe/gplasma/pkg/common/magic-functions" +) + +func (transform *transformPass) Unary(unary *ast2.Unary) *ast3.Call { + var ( + function string + x ast3.Expression + ) + switch unary.Operator { + case ast2.Not: + function = magic_functions.Not + case ast2.Positive: + function = magic_functions.Positive + case ast2.Negative: + function = magic_functions.Negative + case ast2.NegateBits: + function = magic_functions.NegateBits + default: + panic(fmt.Sprintf("unknown binary operator %d", unary.Operator)) + } + x = transform.Expression(unary.X) + return &ast3.Call{ + Function: &ast3.Selector{ + X: x, + Identifier: &ast3.Identifier{ + Symbol: function, + }, + }, + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-while.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-while.go new file mode 100644 index 0000000..e59f4ed --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transform-while.go @@ -0,0 +1,47 @@ +package transformations_1 + +import ( + "github.com/shoriwe/gplasma/pkg/ast2" + "github.com/shoriwe/gplasma/pkg/ast3" +) + +func (transform *transformPass) While(while *ast2.While) []ast3.Node { + setup := make([]ast3.Node, 0, len(while.Setup)) + for _, node := range while.Setup { + setup = append(setup, transform.Node(node)...) + } + startLabel := transform.nextLabel() + endLabel := transform.nextLabel() + condition := &ast3.IfJump{ + Condition: transform.Expression(&ast2.Unary{ + Operator: ast2.Not, + X: while.Condition, + }), + Target: endLabel, + } + body := make([]ast3.Node, 0, len(while.Body)) + for _, node := range while.Body { + body = append(body, transform.Node(node)...) + } + for _, node := range body { + switch n := node.(type) { + case *ast3.ContinueJump: + if n.Target == nil { + n.Target = startLabel + } + case *ast3.BreakJump: + if n.Target == nil { + n.Target = endLabel + } + } + } + result := make([]ast3.Node, 0, 3+len(setup)+len(body)) + result = append(result, setup...) + result = append(result, startLabel, condition) + result = append(result, body...) + result = append(result, &ast3.Jump{ + Target: startLabel, + }) + result = append(result, endLabel) + return result +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transformations.go b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transformations.go new file mode 100644 index 0000000..9df255a --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/passes/transformations-1/transformations.go @@ -0,0 +1,49 @@ +package transformations_1 + +import ( + "fmt" + "github.com/shoriwe/gplasma/pkg/ast2" + "github.com/shoriwe/gplasma/pkg/ast3" + "reflect" +) + +type transformPass struct { + currentLabel int + currentIdentifier int +} + +func (transform *transformPass) Node(node ast2.Node) []ast3.Node { + switch n := node.(type) { + case ast2.Statement: + return transform.Statement(n) + case ast2.Expression: + return []ast3.Node{transform.Expression(n)} + default: + panic(fmt.Sprintf("unknown node type %s", reflect.TypeOf(n).String())) + } +} + +func Transform(program ast2.Program) (ast3.Program, error) { + resultChan := make(chan ast3.Program, 1) + errorChan := make(chan error, 1) + go func(rChan chan ast3.Program, eChan chan error) { + defer func() { + err := recover() + if err != nil { + rChan <- nil + eChan <- err.(error) + } + }() + result := make(ast3.Program, 0, len(program)) + transform := transformPass{ + currentLabel: 1, + currentIdentifier: 1, + } + for _, node := range program { + result = append(result, transform.Node(node)...) + } + rChan <- result + eChan <- nil + }(resultChan, errorChan) + return <-resultChan, <-errorChan +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/reader/reader.go b/vendor/github.com/shoriwe/gplasma/pkg/reader/reader.go index 999a9ee..fea3596 100644 --- a/vendor/github.com/shoriwe/gplasma/pkg/reader/reader.go +++ b/vendor/github.com/shoriwe/gplasma/pkg/reader/reader.go @@ -10,15 +10,21 @@ type Reader interface { Redo() HasNext() bool Index() int + Line() int Char() rune } type StringReader struct { content []rune index int + line int length int } +func (s *StringReader) Line() int { + return s.line +} + func (s *StringReader) Next() { s.index++ } @@ -36,19 +42,24 @@ func (s *StringReader) Index() int { } func (s *StringReader) Char() rune { - return s.content[s.index] + character := s.content[s.index] + if character == '\n' { + s.line++ + } + return character } -func NewStringReader(code string) *StringReader { +func NewStringReader(code string) Reader { runeCode := []rune(code) return &StringReader{ content: runeCode, + line: 1, index: 0, length: len(runeCode), } } -func NewStringReaderFromFile(file io.ReadCloser) *StringReader { +func NewStringReaderFromFile(file io.ReadCloser) Reader { defer file.Close() content, readingError := io.ReadAll(file) if readingError != nil { diff --git a/vendor/github.com/shoriwe/gplasma/pkg/tools/index.go b/vendor/github.com/shoriwe/gplasma/pkg/tools/index.go deleted file mode 100644 index 2afe4b1..0000000 --- a/vendor/github.com/shoriwe/gplasma/pkg/tools/index.go +++ /dev/null @@ -1,17 +0,0 @@ -package tools - -import "github.com/shoriwe/gplasma/pkg/errors" - -func CalcIndex(index64 int64, length int) (int, *errors.Error) { - index := int(index64) - if length <= index { - return 0, errors.NewIndexOutOfRangeError(errors.UnknownLine, length, index) - } - if index < 0 { - index = length + index - if index < 0 { - return 0, errors.NewIndexOutOfRangeError(errors.UnknownLine, length, index) - } - } - return index, nil -} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/tools/string.go b/vendor/github.com/shoriwe/gplasma/pkg/tools/string.go deleted file mode 100644 index 39a036d..0000000 --- a/vendor/github.com/shoriwe/gplasma/pkg/tools/string.go +++ /dev/null @@ -1,75 +0,0 @@ -package tools - -import ( - "strconv" -) - -var directCharEscapeValue = map[rune][]rune{ - 'a': {7}, - 'b': {8}, - 'e': {'\\', 'e'}, - 'f': {12}, - 'n': {10}, - 'r': {13}, - 't': {9}, - '?': {'\\', '?'}, -} - -func Repeat(s string, times int64) string { - result := "" - for i := int64(0); i < times; i++ { - result += s - } - return result -} - -func ReplaceEscaped(s []rune) []rune { - sLength := len(s) - escaped := false - var result []rune - for index := 0; index < sLength; index++ { - char := s[index] - if escaped { - switch char { - case 'a', 'b', 'e', 'f', 'n', 'r', 't', '?': - // Replace char based - result = append(result, directCharEscapeValue[char]...) - case '\\', '\'', '"', '`': - // Replace escaped literals - result = append(result, char) - case 'x': - // Replace hex with numbers - index++ - a := s[index] - index++ - b := s[index] - number, parsingError := strconv.ParseUint(string([]rune{a, b}), 16, 32) - if parsingError != nil { - panic(parsingError) - } - result = append(result, rune(number)) - case 'u': - // Replace unicode with numbers - index++ - a := s[index] - index++ - b := s[index] - index++ - c := s[index] - index++ - d := s[index] - number, parsingError := strconv.ParseUint(string([]rune{a, b, c, d}), 16, 32) - if parsingError != nil { - panic(parsingError) - } - result = append(result, rune(number)) - } - escaped = false - } else if char == '\\' { - escaped = true - } else { - result = append(result, char) - } - } - return result -} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/vm/ToDo.md b/vendor/github.com/shoriwe/gplasma/pkg/vm/ToDo.md deleted file mode 100644 index 981ef47..0000000 --- a/vendor/github.com/shoriwe/gplasma/pkg/vm/ToDo.md +++ /dev/null @@ -1,6 +0,0 @@ -# ToDos - -- [ ] Iter -- [ ] Hash Table -- [ ] Dir Hash Table -- [X] Tuple, Array and String Indexed by Integer and Tuples of Integers \ No newline at end of file diff --git a/vendor/github.com/shoriwe/gplasma/pkg/vm/array.go b/vendor/github.com/shoriwe/gplasma/pkg/vm/array.go index 983527f..3efa62d 100644 --- a/vendor/github.com/shoriwe/gplasma/pkg/vm/array.go +++ b/vendor/github.com/shoriwe/gplasma/pkg/vm/array.go @@ -1,309 +1,248 @@ package vm -import "github.com/shoriwe/gplasma/pkg/tools" +import ( + magic_functions "github.com/shoriwe/gplasma/pkg/common/magic-functions" +) -func (p *Plasma) NewArray(context *Context, isBuiltIn bool, content []*Value) *Value { - array := p.NewValue(context, isBuiltIn, ArrayName, nil, context.PeekSymbolTable()) - array.BuiltInTypeId = ArrayId - array.Content = content - p.ArrayInitialize(isBuiltIn)(context, array) - array.SetOnDemandSymbol(Self, - func() *Value { - return array - }, +func (plasma *Plasma) arrayClass() *Value { + class := plasma.NewValue(plasma.rootSymbols, BuiltInClassId, plasma.class) + class.SetAny( + Callback(func(argument ...*Value) (*Value, error) { + return plasma.NewArray(argument[0].Values()), nil + }), ) - return array + return class } -func (p *Plasma) ArrayInitialize(isBuiltIn bool) ConstructorCallBack { - return func(context *Context, object *Value) *Value { - object.SetOnDemandSymbol(Add, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - if !arguments[0].IsTypeById(ArrayId) { - return p.NewInvalidTypeError(context, arguments[0].GetClass(p).Name, ArrayName), false - } - return p.NewArray(context, false, append(self.Content, arguments[0].Content...)), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightAdd, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - if !arguments[0].IsTypeById(ArrayId) { - return p.NewInvalidTypeError(context, arguments[0].GetClass(p).Name, ArrayName), false - } - return p.NewArray(context, false, append(arguments[0].Content, self.Content...)), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Mul, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - right := arguments[0] - switch right.BuiltInTypeId { - case IntegerId: - content, repetitionError := p.Repeat(context, self.Content, - right.Integer) - if repetitionError != nil { - return repetitionError, false - } - return p.NewArray(context, false, content), true - default: - return p.NewInvalidTypeError(context, right.TypeName(), IntegerName, FloatName, StringName, ArrayName, TupleName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightMul, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - left := arguments[0] - switch left.BuiltInTypeId { - case IntegerId: - content, repetitionError := p.Repeat(context, self.Content, - left.Integer, - ) - if repetitionError != nil { - return repetitionError, false - } - return p.NewArray(context, false, content), true - default: - return p.NewInvalidTypeError(context, left.TypeName(), IntegerName, FloatName, StringName, ArrayName, TupleName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Equals, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - return p.ContentEquals(context, self, arguments[0]) - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightEquals, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - return p.ContentEquals(context, arguments[0], self) - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(NotEquals, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - return p.ContentNotEquals(context, self, arguments[0]) - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightNotEquals, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - return p.ContentNotEquals(context, arguments[0], self) - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Contains, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - return p.ContentContains(context, self, arguments[0]) - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Hash, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(_ *Value, _ ...*Value) (*Value, bool) { - return p.NewUnhashableTypeError(context, object.GetClass(p)), false - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Copy, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.ContentCopy(context, self) - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Index, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - return p.ContentIndex(context, self, arguments[0]) - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Assign, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 2, - func(self *Value, arguments ...*Value) (*Value, bool) { - return p.ContentAssign(context, self, arguments[0], arguments[1]) - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Iter, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.ContentIterator(context, self) - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(ToString, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.ContentToString(context, self) - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(ToBool, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.InterpretAsBool(len(self.Content) != 0), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(ToArray, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return self, true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(ToTuple, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.NewTuple(context, false, append([]*Value{}, self.Content...)), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Append, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - self.Content = append(self.Content, arguments[0]) - return p.GetNone(), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Length, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, arguments ...*Value) (*Value, bool) { - return p.NewInteger(context, false, int64(len(self.Content))), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Pop, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, arguments ...*Value) (*Value, bool) { - length := len(self.Content) - if length > 0 { - result := self.Content[length-1] - self.Content = self.Content[:length-1] - return result, true - } - return p.NewIndexOutOfRange(context, 0, 0), false - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Delete, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - if !arguments[0].IsTypeById(IntegerId) { - return p.NewInvalidTypeError(context, arguments[0].GetClass(p).Name, IntegerName), false - } - contentLength := len(self.Content) - realIndex, indexCalculationError := tools.CalcIndex(arguments[0].Integer, contentLength) - if indexCalculationError != nil { - return p.NewIndexOutOfRange(context, contentLength, arguments[0].Integer), false - } - self.Content = append(self.Content[:realIndex], self.Content[realIndex+1:]...) - return p.GetNone(), true - }, - ), - ) - }, - ) - return nil - } +/* +NewArray magic function: +In __in__ +Equal __equal__ +NotEqual __not_equal__ +Mul __mul__ +Length __len__ +Bool __bool__ +String __string__ +Bytes __bytes__ +Array __array__ +Tuple __tuple__ +Get __get__ +Set __set__ +Iter __iter__ +Append append +Clear clear +Index index +Pop pop +Insert insert +Remove remove +*/ +func (plasma *Plasma) NewArray(values []*Value) *Value { + result := plasma.NewValue(plasma.rootSymbols, ArrayId, plasma.array) + result.SetAny(values) + result.Set(magic_functions.In, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + for _, value := range result.GetValues() { + if value.Equal(argument[0]) { + return plasma.true, nil + } + } + return plasma.false, nil + })) + result.Set(magic_functions.Equal, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case ArrayId: + otherValues := argument[0].GetValues() + for index, value := range result.GetValues() { + if !value.Equal(otherValues[index]) { + return plasma.false, nil + } + } + } + return plasma.true, nil + })) + result.Set(magic_functions.NotEqual, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case ArrayId: + otherValues := argument[0].GetValues() + for index, value := range result.GetValues() { + if value.Equal(otherValues[index]) { + return plasma.false, nil + } + } + } + return plasma.true, nil + })) + result.Set(magic_functions.Mul, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case IntId: + times := argument[0].GetInt64() + currentValues := result.GetValues() + newValues := make([]*Value, 0, int64(len(currentValues))*times) + for i := int64(0); i < times; i++ { + for _, value := range currentValues { + newValues = append(newValues, value) + } + } + return plasma.NewArray(newValues), nil + default: + return nil, NotOperable + } + })) + result.Set(magic_functions.Length, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewInt(int64(len(result.GetValues()))), nil + })) + result.Set(magic_functions.Bool, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewBool(len(result.GetValues()) > 0), nil + })) + result.Set(magic_functions.String, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + var rawString []byte + rawString = append(rawString, '[') + for index, value := range result.GetValues() { + if index != 0 { + rawString = append(rawString, ',', ' ') + } + rawString = append(rawString, value.String()...) + } + rawString = append(rawString, ']') + return plasma.NewString(rawString), nil + })) + result.Set(magic_functions.Bytes, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + var rawString []byte + for _, value := range result.GetValues() { + rawString = append(rawString, byte(value.Int())) + } + rawString = append(rawString, ']') + return plasma.NewBytes(rawString), nil + })) + result.Set(magic_functions.Array, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return result, nil + })) + result.Set(magic_functions.Tuple, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewTuple(result.GetValues()), nil + })) + result.Set(magic_functions.Get, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case IntId: + return result.GetValues()[argument[0].GetInt64()], nil + default: + return nil, NotIndexable + } + })) + result.Set(magic_functions.Set, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case IntId: + result.GetValues()[argument[0].GetInt64()] = argument[1] + return plasma.none, nil + default: + return nil, NotIndexable + } + })) + result.Set(magic_functions.Iter, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + iter := plasma.NewValue(result.vtable, ValueId, plasma.value) + iter.SetAny(int64(0)) + iter.Set(magic_functions.HasNext, plasma.NewBuiltInFunction(iter.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewBool(iter.GetInt64() < int64(len(result.GetValues()))), nil + }, + )) + iter.Set(magic_functions.Next, plasma.NewBuiltInFunction(iter.vtable, + func(argument ...*Value) (*Value, error) { + currentValues := result.GetValues() + index := iter.GetInt64() + iter.SetAny(index + 1) + if index < int64(len(currentValues)) { + return currentValues[index], nil + } + return plasma.none, nil + }, + )) + return iter, nil + })) + result.Set(magic_functions.Append, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + result.SetAny(append(result.GetValues(), argument[0])) + return plasma.none, nil + }, + )) + result.Set(magic_functions.Clear, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + result.SetAny([]*Value{}) + return plasma.none, nil + }, + )) + result.Set(magic_functions.Index, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + for index, value := range result.GetValues() { + if value.Equal(argument[0]) { + return plasma.NewInt(int64(index)), nil + } + } + return plasma.NewInt(-1), nil + }, + )) + result.Set(magic_functions.Pop, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + currentValues := result.GetValues() + r := currentValues[len(currentValues)-1] + currentValues = currentValues[:len(currentValues)-1] + result.SetAny(currentValues) + return r, nil + }, + )) + result.Set(magic_functions.Insert, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + index := argument[0].Int() + value := argument[1] + currentValues := result.GetValues() + newValues := make([]*Value, 0, 1+int64(len(currentValues))) + newValues = append(newValues, currentValues[:index]...) + newValues = append(newValues, value) + newValues = append(newValues, currentValues[index:]...) + result.SetAny(newValues) + return plasma.none, nil + }, + )) + result.Set(magic_functions.Remove, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + index := argument[0].Int() + currentValues := result.GetValues() + newValues := make([]*Value, 0, 1+int64(len(currentValues))) + newValues = append(newValues, currentValues[:index]...) + newValues = append(newValues, currentValues[index+1:]...) + result.SetAny(newValues) + return plasma.none, nil + }, + )) + return result } diff --git a/vendor/github.com/shoriwe/gplasma/pkg/vm/bool.go b/vendor/github.com/shoriwe/gplasma/pkg/vm/bool.go index 5a4ede2..a62b63a 100644 --- a/vendor/github.com/shoriwe/gplasma/pkg/vm/bool.go +++ b/vendor/github.com/shoriwe/gplasma/pkg/vm/bool.go @@ -1,184 +1,105 @@ package vm -func (p *Plasma) QuickGetBool(context *Context, value *Value) (bool, *Value) { - if value.BuiltInTypeId == BoolId { - return value.Bool, nil - } - valueToBool, getError := value.Get(p, context, ToBool) - if getError != nil { - return false, getError - } - valueBool, success := p.CallFunction(context, valueToBool) - if !success { - return false, valueBool - } - if !valueBool.IsTypeById(BoolId) { - return false, p.NewInvalidTypeError(context, value.TypeName(), BoolName) - } - return valueBool.Bool, nil -} - -func (p *Plasma) NewBool(context *Context, isBuiltIn bool, value bool) *Value { - bool_ := p.NewValue(context, isBuiltIn, BoolName, nil, context.PeekSymbolTable()) - bool_.BuiltInTypeId = BoolId - bool_.Bool = value - p.BoolInitialize(isBuiltIn)(context, bool_) - bool_.SetOnDemandSymbol(Self, - func() *Value { - return bool_ - }, - ) - return bool_ -} - -func (p *Plasma) GetFalse() *Value { - return p.ForceMasterGetAny(FalseName) -} +import magic_functions "github.com/shoriwe/gplasma/pkg/common/magic-functions" -func (p *Plasma) GetTrue() *Value { - return p.ForceMasterGetAny(TrueName) +func (plasma *Plasma) boolClass() *Value { + class := plasma.NewValue(plasma.rootSymbols, BuiltInClassId, plasma.class) + class.SetAny(Callback(func(argument ...*Value) (*Value, error) { + return plasma.NewBool(argument[0].Bool()), nil + })) + return class } -func (p *Plasma) BoolInitialize(isBuiltIn bool) ConstructorCallBack { - return func(context *Context, object *Value) *Value { - object.SetOnDemandSymbol(Equals, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - right := arguments[0] - if !right.IsTypeById(BoolId) { - return p.GetFalse(), true - } - return p.InterpretAsBool(self.Bool == right.Bool), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightEquals, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - left := arguments[0] - if !left.IsTypeById(BoolId) { - return p.GetFalse(), true - } - return p.InterpretAsBool(left.Bool == self.Bool), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(NotEquals, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - right := arguments[0] - if right.BuiltInTypeId != BoolId { - return p.GetFalse(), true - } - return p.InterpretAsBool(self.Bool != right.Bool), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightNotEquals, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - left := arguments[0] - if left.BuiltInTypeId != BoolId { - return p.GetFalse(), true - } - return p.InterpretAsBool(left.Bool != self.Bool), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Copy, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.InterpretAsBool(self.Bool), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Hash, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - if self.Bool { - return p.NewInteger(context, false, 1), true - } - return p.NewInteger(context, false, 0), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(ToInteger, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - if self.Bool { - return p.NewInteger(context, false, 1), true - } - return p.NewInteger(context, false, 0), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(ToFloat, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - if self.Bool { - return p.NewFloat(context, false, 1), true - } - return p.NewFloat(context, false, 0), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(ToString, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - if self.Bool { - return p.NewString(context, false, TrueName), true - } - return p.NewString(context, false, FalseName), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(ToBool, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.InterpretAsBool(self.Bool), true - }, - ), - ) - }, - ) - return nil +/* +NewBool magic function: +Not __not__ +And __and__ +Or __or__ +Xor __xor__ +Equal __equal__ +NotEqual __not_equal__ +Bool __bool__ +String __string__ +Int __int__ +Float __float__ +Bytes __bytes__ +Copy __copy__ +*/ +func (plasma *Plasma) NewBool(b bool) *Value { + if b && plasma.true != nil { + return plasma.true + } else if !b && plasma.false != nil { + return plasma.false } + result := plasma.NewValue(plasma.rootSymbols, BoolId, plasma.bool) + result.SetAny(b) + result.Set(magic_functions.Not, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewBool(!result.GetBool()), nil + }, + )) + result.Set(magic_functions.Equal, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case BoolId: + return plasma.NewBool(result.GetBool() == argument[0].GetBool()), nil + } + return plasma.false, nil + }, + )) + result.Set(magic_functions.NotEqual, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case BoolId: + return plasma.NewBool(result.GetBool() != argument[0].GetBool()), nil + } + return plasma.true, nil + }, + )) + result.Set(magic_functions.Bool, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return result, nil + }, + )) + result.Set(magic_functions.String, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewString([]byte(result.String())), nil + }, + )) + result.Set(magic_functions.Int, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + if result.GetBool() { + return plasma.NewInt(1), nil + } + return plasma.NewInt(0), nil + }, + )) + result.Set(magic_functions.Float, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + if result.GetBool() { + return plasma.NewFloat(1), nil + } + return plasma.NewFloat(0), nil + }, + )) + result.Set(magic_functions.Bytes, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewBytes([]byte(result.String())), nil + }, + )) + result.Set(magic_functions.Copy, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return result, nil + }, + )) + return result } diff --git a/vendor/github.com/shoriwe/gplasma/pkg/vm/bytecode.go b/vendor/github.com/shoriwe/gplasma/pkg/vm/bytecode.go deleted file mode 100644 index 212c42e..0000000 --- a/vendor/github.com/shoriwe/gplasma/pkg/vm/bytecode.go +++ /dev/null @@ -1,64 +0,0 @@ -package vm - -type Instruction struct { - OpCode uint8 - Line int -} - -func NewInstruction(opCode uint8) Instruction { - return Instruction{ - OpCode: opCode, - } -} - -type Code struct { - Instruction Instruction - Value interface{} - Line int -} - -func NewCode(opCode uint8, line int, value interface{}) *Code { - return &Code{ - Instruction: NewInstruction(opCode), - Value: value, - Line: line, - } -} - -type Bytecode struct { - instructions []*Code - length int - index int -} - -func (bytecode *Bytecode) HasNext() bool { - return bytecode.index < bytecode.length -} - -func (bytecode *Bytecode) Peek() *Code { - return bytecode.instructions[bytecode.index] -} - -func (bytecode *Bytecode) Next() *Code { - result := bytecode.instructions[bytecode.index] - bytecode.index++ - return result -} - -func (bytecode *Bytecode) NextN(n int) []*Code { - result := bytecode.instructions[bytecode.index : bytecode.index+n] - bytecode.index += n - return result -} - -func (bytecode *Bytecode) Jump(offset int) { - bytecode.index += offset -} - -func NewBytecodeFromArray(codes []*Code) *Bytecode { - return &Bytecode{ - instructions: codes, - length: len(codes), - index: 0, - } -} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/vm/bytes.go b/vendor/github.com/shoriwe/gplasma/pkg/vm/bytes.go index 16cd0ba..03ff838 100644 --- a/vendor/github.com/shoriwe/gplasma/pkg/vm/bytes.go +++ b/vendor/github.com/shoriwe/gplasma/pkg/vm/bytes.go @@ -2,312 +2,238 @@ package vm import ( "bytes" - "encoding/binary" + magic_functions "github.com/shoriwe/gplasma/pkg/common/magic-functions" ) -func (p *Plasma) NewBytes(context *Context, isBuiltIn bool, content []uint8) *Value { - bytes_ := p.NewValue(context, isBuiltIn, BytesName, nil, context.PeekSymbolTable()) - bytes_.BuiltInTypeId = BytesId - bytes_.Bytes = content - p.BytesInitialize(isBuiltIn)(context, bytes_) - bytes_.SetOnDemandSymbol(Self, - func() *Value { - return bytes_ - }, - ) - return bytes_ +func (plasma *Plasma) bytesClass() *Value { + class := plasma.NewValue(plasma.rootSymbols, BuiltInClassId, plasma.class) + class.SetAny(Callback(func(argument ...*Value) (*Value, error) { + return plasma.NewBytes(argument[0].Contents()), nil + })) + return class } -func (p *Plasma) BytesInitialize(isBuiltIn bool) ConstructorCallBack { - return func(context *Context, object *Value) *Value { - object.SetOnDemandSymbol(Length, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, arguments ...*Value) (*Value, bool) { - return p.NewInteger(context, false, int64(len(self.Bytes))), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Add, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - right := arguments[0] - if !right.IsTypeById(BytesId) { - return p.NewInvalidTypeError(context, right.TypeName(), BytesName), false - } - var newContent []uint8 - copy(newContent, self.Bytes) - newContent = append(newContent, right.Bytes...) - return p.NewBytes(context, false, newContent), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightAdd, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - left := arguments[0] - if !left.IsTypeById(BytesId) { - return p.NewInvalidTypeError(context, left.TypeName(), BytesName), false - } - var newContent []uint8 - copy(newContent, left.Bytes) - newContent = append(newContent, self.Bytes...) - return p.NewBytes(context, false, newContent), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Mul, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - right := arguments[0] - if !right.IsTypeById(BytesId) { - return p.NewInvalidTypeError(context, right.TypeName(), IntegerName), false - } - return p.NewBytes(context, false, bytes.Repeat(self.Bytes, int(right.Integer))), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightMul, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - left := arguments[0] - if !left.IsTypeById(IntegerId) { - return p.NewInvalidTypeError(context, left.TypeName(), IntegerName), false - } - return p.NewBytes(context, false, bytes.Repeat(left.Bytes, int(self.Integer))), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Equals, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - right := arguments[0] - if !right.IsTypeById(BytesId) { - return p.GetFalse(), true - } - if len(self.Bytes) != len(right.Bytes) { - return p.GetFalse(), true - } - return p.InterpretAsBool(bytes.Compare(self.Bytes, right.Bytes) == 0), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightEquals, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - left := arguments[0] - if !left.IsTypeById(BytesId) { - return p.GetFalse(), true - } - if len(left.Bytes) != len(self.Bytes) { - return p.GetFalse(), true - } - return p.InterpretAsBool(bytes.Compare(left.Bytes, self.Bytes) == 0), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(NotEquals, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - right := arguments[0] - if !right.IsTypeById(BytesId) { - return p.GetFalse(), true - } - if len(self.Bytes) != len(right.Bytes) { - return p.GetFalse(), true - } - return p.InterpretAsBool(bytes.Compare(self.Bytes, right.Bytes) != 0), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightNotEquals, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - left := arguments[0] - if !left.IsTypeById(BytesId) { - return p.GetFalse(), true - } - if len(left.Bytes) != len(self.Bytes) { - return p.GetFalse(), true - } - return p.InterpretAsBool(bytes.Compare(left.Bytes, self.Bytes) != 0), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Hash, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - selfHash := p.HashBytes(append(self.Bytes, []byte("Bytes")...)) - return p.NewInteger(context, false, selfHash), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Copy, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - var newBytes []uint8 - copy(newBytes, self.Bytes) - return p.NewBytes(context, false, newBytes), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Index, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - return p.BytesIndex(context, self, arguments[0]) - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Iter, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.BytesIterator(context, self) - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(ToInteger, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.NewInteger(context, false, - int64(binary.BigEndian.Uint32(self.Bytes)), - ), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(ToString, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.NewString(context, false, string(self.Bytes)), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(ToBool, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.InterpretAsBool(len(self.Bytes) != 0), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(ToArray, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.BytesToContent(context, self, ArrayId) - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(ToTuple, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.BytesToContent(context, self, TupleId) - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Replace, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - if !arguments[0].IsTypeById(BytesId) { - return p.NewInvalidTypeError(context, arguments[0].GetClass(p).Name, BytesName), false - } - var subBytes []*Value - for _, s := range bytes.Split(self.Bytes, arguments[0].Bytes) { - subBytes = append(subBytes, p.NewBytes(context, false, s)) - } - return p.NewArray(context, false, subBytes), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Replace, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 2, - func(self *Value, arguments ...*Value) (*Value, bool) { - if !arguments[0].IsTypeById(BytesId) { - return p.NewInvalidTypeError(context, arguments[0].GetClass(p).Name, BytesName), false - } - if !arguments[1].IsTypeById(BytesId) { - return p.NewInvalidTypeError(context, arguments[1].GetClass(p).Name, BytesName), false - } - return p.NewBytes(context, false, bytes.ReplaceAll(self.Bytes, arguments[0].Bytes, arguments[1].Bytes)), true - }, - ), - ) - }, - ) - return nil - } +/* +NewBytes magic function: +Equal __equal__ +NotEqual __not_equal__ +Add __add__ +Mul __mul__ +Length __len__ +Bool __bool__ +String __string__ +Bytes __bytes__ +Array __array__ +Tuple __tuple__ +Get __get__ +Copy __copy__ +Iter __iter__ +Join join +Split split +Upper upper +Lower lower +Count count +Index Index +*/ +func (plasma *Plasma) NewBytes(contents []byte) *Value { + result := plasma.NewValue(plasma.rootSymbols, BytesId, plasma.bytes) + result.SetAny(contents) + result.Set(magic_functions.In, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case BytesId: + return plasma.NewBool(bytes.Contains(result.GetBytes(), argument[0].GetBytes())), nil + case IntId: + i := argument[0].GetInt64() + for _, b := range result.GetBytes() { + if int64(b) == i { + return plasma.true, nil + } + } + return plasma.false, nil + } + return plasma.false, nil + }, + )) + result.Set(magic_functions.Equal, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewBool(result.Equal(argument[0])), nil + }, + )) + result.Set(magic_functions.NotEqual, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewBool(!result.Equal(argument[0])), nil + }, + )) + result.Set(magic_functions.Add, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case BytesId: + s := result.GetBytes() + otherS := argument[0].GetBytes() + newString := make([]byte, 0, len(s)+len(otherS)) + newString = append(newString, s...) + newString = append(newString, otherS...) + return plasma.NewBytes(newString), nil + } + return nil, NotOperable + }, + )) + result.Set(magic_functions.Mul, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case IntId: + s := result.GetBytes() + times := argument[0].GetInt64() + return plasma.NewBytes(bytes.Repeat(s, int(times))), nil + } + return nil, NotOperable + }, + )) + result.Set(magic_functions.Length, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewInt(int64(len(result.GetBytes()))), nil + }, + )) + result.Set(magic_functions.Bool, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewBool(len(result.GetBytes()) > 0), nil + }, + )) + result.Set(magic_functions.String, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewString(result.GetBytes()), nil + }, + )) + result.Set(magic_functions.Bytes, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return result, nil + }, + )) + result.Set(magic_functions.Array, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + s := result.GetBytes() + values := make([]*Value, 0, len(s)) + for _, b := range s { + values = append(values, plasma.NewInt(int64(b))) + } + return plasma.NewArray(values), nil + }, + )) + result.Set(magic_functions.Tuple, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + s := result.GetBytes() + values := make([]*Value, 0, len(s)) + for _, b := range s { + values = append(values, plasma.NewInt(int64(b))) + } + return plasma.NewTuple(values), nil + }, + )) + result.Set(magic_functions.Get, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case IntId: + s := result.GetBytes() + index := argument[0].GetInt64() + return plasma.NewInt(int64(s[index])), nil + case TupleId: + s := result.GetBytes() + values := argument[0].GetValues() + startIndex := values[0].GetInt64() + endIndex := values[1].GetInt64() + return plasma.NewBytes(s[startIndex:endIndex]), nil + } + return nil, NotIndexable + }, + )) + result.Set(magic_functions.Copy, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + s := result.GetBytes() + newS := make([]byte, len(s)) + copy(newS, s) + return plasma.NewBytes(newS), nil + }, + )) + result.Set(magic_functions.Iter, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + iter := plasma.NewValue(result.vtable, ValueId, plasma.value) + iter.SetAny(int64(0)) + iter.Set(magic_functions.HasNext, plasma.NewBuiltInFunction(iter.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewBool(iter.GetInt64() < int64(len(result.GetBytes()))), nil + }, + )) + iter.Set(magic_functions.Next, plasma.NewBuiltInFunction(iter.vtable, + func(argument ...*Value) (*Value, error) { + currentBytes := result.GetBytes() + index := iter.GetInt64() + iter.SetAny(index + 1) + if index < int64(len(currentBytes)) { + return plasma.NewBytes([]byte{currentBytes[index]}), nil + } + return plasma.none, nil + }, + )) + return iter, nil + }, + )) + result.Set(magic_functions.Join, plasma.NewBuiltInFunction(result.vtable, + func(argument ...*Value) (*Value, error) { + values := argument[0].Values() + valuesBytes := make([][]byte, 0, len(values)) + for _, value := range values { + valuesBytes = append(valuesBytes, []byte(value.String())) + } + return plasma.NewBytes(bytes.Join(valuesBytes, []byte(result.String()))), nil + }, + )) + result.Set(magic_functions.Split, plasma.NewBuiltInFunction(result.vtable, + func(argument ...*Value) (*Value, error) { + sep := argument[0].String() + splitted := bytes.Split(result.GetBytes(), []byte(sep)) + values := make([]*Value, 0, len(splitted)) + for _, b := range splitted { + values = append(values, plasma.NewBytes(b)) + } + return plasma.NewTuple(values), nil + }, + )) + result.Set(magic_functions.Upper, plasma.NewBuiltInFunction(result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewBytes(bytes.ToUpper(result.GetBytes())), nil + }, + )) + result.Set(magic_functions.Lower, plasma.NewBuiltInFunction(result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewBytes(bytes.ToLower(result.GetBytes())), nil + }, + )) + result.Set(magic_functions.Count, plasma.NewBuiltInFunction(result.vtable, + func(argument ...*Value) (*Value, error) { + sep := argument[0].String() + return plasma.NewInt(int64(bytes.Count(result.GetBytes(), []byte(sep)))), nil + }, + )) + result.Set(magic_functions.Index, plasma.NewBuiltInFunction(result.vtable, + func(argument ...*Value) (*Value, error) { + sep := argument[0].String() + return plasma.NewInt(int64(bytes.Index(result.GetBytes(), []byte(sep)))), nil + }, + )) + return result } diff --git a/vendor/github.com/shoriwe/gplasma/pkg/vm/call.go b/vendor/github.com/shoriwe/gplasma/pkg/vm/call.go deleted file mode 100644 index 1500134..0000000 --- a/vendor/github.com/shoriwe/gplasma/pkg/vm/call.go +++ /dev/null @@ -1,174 +0,0 @@ -package vm - -func (p *Plasma) CallableInitialize(isBuiltIn bool) ConstructorCallBack { - return func(context *Context, object *Value) *Value { - object.SetOnDemandSymbol(Call, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(_ *Value, _ ...*Value) (*Value, bool) { - return p.NewNotImplementedCallableError(context, Call), false - }, - ), - ) - }, - ) - return nil - } -} - -func (p *Plasma) CallFunction(context *Context, function *Value, arguments ...*Value) (*Value, bool) { - var ( - callFunction *Value - result *Value - callError *Value - success bool - ) - switch function.BuiltInTypeId { - case FunctionId: - callFunction = function - case TypeId: - result, success = p.ConstructObject(context, function, function.SymbolTable().Parent) - if !success { - return result, false - } - resultInitialize, getError := result.Get(p, context, Initialize) - if getError != nil { - return getError, false - } - callError, success = p.CallFunction(context, resultInitialize, arguments...) - // Construct the object and initialize it - if !success { - return callError, false - } - return result, true - default: - call, getError := function.Get(p, context, Call) - if getError != nil { - return getError, false - } - if !call.IsTypeById(FunctionId) { - return p.NewInvalidTypeError(context, function.TypeName(), CallableName), false - } - callFunction = call - } - if callFunction.Callable.NumberOfArguments() != len(arguments) { - // Return Here a error related to number of arguments - return p.NewInvalidNumberOfArgumentsError(context, len(arguments), callFunction.Callable.NumberOfArguments()), false - } - symbols := NewSymbolTable(function.SymbolTable().Parent) - self, callback, code := callFunction.Callable.Call() - if self != nil { - symbols.Set(Self, self) - } else { - symbols.Set(Self, function) - } - context.PushSymbolTable(symbols) - if callback != nil { - result, success = callback(self, arguments...) - } else if code != nil { - // Load the arguments - for i := len(arguments) - 1; i > -1; i-- { - context.PushObject(arguments[i]) - } - result, success = p.Execute(context, NewBytecodeFromArray(code)) - } else { - panic("callback and code are nil") - } - context.PopSymbolTable() - if !success { - return result, false - } - return result, true -} - -type FunctionCallback func(*Value, ...*Value) (*Value, bool) - -type Callable interface { - NumberOfArguments() int - Call() (*Value, FunctionCallback, []*Code) // self should return directly the object or the code of the function -} - -type PlasmaFunction struct { - numberOfArguments int - Code []*Code -} - -func (p *PlasmaFunction) NumberOfArguments() int { - return p.numberOfArguments -} - -func (p *PlasmaFunction) Call() (*Value, FunctionCallback, []*Code) { - return nil, nil, p.Code -} - -func NewPlasmaFunction(numberOfArguments int, code []*Code) *PlasmaFunction { - return &PlasmaFunction{ - numberOfArguments: numberOfArguments, - Code: code, - } -} - -type PlasmaClassFunction struct { - numberOfArguments int - Code []*Code - Self *Value -} - -func (p *PlasmaClassFunction) NumberOfArguments() int { - return p.numberOfArguments -} - -func (p *PlasmaClassFunction) Call() (*Value, FunctionCallback, []*Code) { - return p.Self, nil, p.Code -} - -func NewPlasmaClassFunction(self *Value, numberOfArguments int, code []*Code) *PlasmaClassFunction { - return &PlasmaClassFunction{ - numberOfArguments: numberOfArguments, - Code: code, - Self: self, - } -} - -type BuiltInFunction struct { - numberOfArguments int - callback FunctionCallback -} - -func (g *BuiltInFunction) NumberOfArguments() int { - return g.numberOfArguments -} - -func (g *BuiltInFunction) Call() (*Value, FunctionCallback, []*Code) { - return nil, g.callback, nil -} - -func NewBuiltInFunction(numberOfArguments int, callback FunctionCallback) *BuiltInFunction { - return &BuiltInFunction{ - numberOfArguments: numberOfArguments, - callback: callback, - } -} - -type BuiltInClassFunction struct { - numberOfArguments int - callback FunctionCallback - Self *Value -} - -func (g *BuiltInClassFunction) NumberOfArguments() int { - return g.numberOfArguments -} - -func (g *BuiltInClassFunction) Call() (*Value, FunctionCallback, []*Code) { - return g.Self, g.callback, nil -} - -func NewBuiltInClassFunction(self *Value, numberOfArguments int, callback FunctionCallback) *BuiltInClassFunction { - return &BuiltInClassFunction{ - numberOfArguments: numberOfArguments, - callback: callback, - Self: self, - } -} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/vm/class.go b/vendor/github.com/shoriwe/gplasma/pkg/vm/class.go new file mode 100644 index 0000000..93910e3 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/vm/class.go @@ -0,0 +1,34 @@ +package vm + +import magic_functions "github.com/shoriwe/gplasma/pkg/common/magic-functions" + +func (plasma *Plasma) metaClass() *Value { + plasma.class = plasma.NewValue(plasma.rootSymbols, BuiltInClassId, plasma.class) + plasma.class.class = plasma.class + plasma.class.SetAny(Callback(func(argument ...*Value) (*Value, error) { + return plasma.NewClass(), nil + })) + return plasma.class +} + +/* +NewClass magic function: +Equal __equal__ +NotEqual __not_equal__ +*/ +func (plasma *Plasma) NewClass() *Value { + result := plasma.NewValue(plasma.rootSymbols, BuiltInClassId, plasma.class) + result.Set(magic_functions.Equal, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewBool(result == argument[0]), nil + }, + )) + result.Set(magic_functions.NotEqual, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewBool(result != argument[0]), nil + }, + )) + return result +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/vm/config.go b/vendor/github.com/shoriwe/gplasma/pkg/vm/config.go new file mode 100644 index 0000000..d67bd54 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/vm/config.go @@ -0,0 +1,5 @@ +package vm + +const ( + MaxDoCallSearch = 3 +) diff --git a/vendor/github.com/shoriwe/gplasma/pkg/vm/constructor.go b/vendor/github.com/shoriwe/gplasma/pkg/vm/constructor.go deleted file mode 100644 index fadf3eb..0000000 --- a/vendor/github.com/shoriwe/gplasma/pkg/vm/constructor.go +++ /dev/null @@ -1,78 +0,0 @@ -package vm - -func (p *Plasma) constructSubClass(context *Context, subClass *Value, object *Value) *Value { - for _, subSubClass := range subClass.subClasses { - object.SymbolTable().Parent = subSubClass.symbols.Parent - subSubClassConstructionError := p.constructSubClass(context, subSubClass, object) - if subSubClassConstructionError != nil { - return subSubClassConstructionError - } - } - object.SymbolTable().Parent = subClass.symbols.Parent - baseInitializationError := subClass.Constructor.Construct(context, p, object) - if baseInitializationError != nil { - return baseInitializationError - } - return nil -} - -func (p *Plasma) ConstructObject(context *Context, type_ *Value, parent *SymbolTable) (*Value, bool) { - object := p.NewValue(context, false, type_.Name, type_.subClasses, parent) - for _, subclass := range object.subClasses { - subClassConstructionError := p.constructSubClass(context, subclass, object) - if subClassConstructionError != nil { - return subClassConstructionError, false - } - } - object.SymbolTable().Parent = parent - object.class = type_ - baseInitializationError := type_.Constructor.Construct(context, p, object) - if baseInitializationError != nil { - return baseInitializationError, false - } - return object, true -} - -type Constructor interface { - Construct(*Context, *Plasma, *Value) *Value -} - -type PlasmaConstructor struct { - Constructor - Code []*Code -} - -func (c *PlasmaConstructor) Construct(context *Context, vm *Plasma, object *Value) *Value { - context.PushSymbolTable(object.SymbolTable()) - context.PushObject(object) - executionError, success := vm.Execute(context, NewBytecodeFromArray(c.Code)) - context.PopSymbolTable() - context.PopObject() - if !success { - return executionError - } - return nil -} - -func NewPlasmaConstructor(code []*Code) *PlasmaConstructor { - return &PlasmaConstructor{ - Code: code, - } -} - -type ConstructorCallBack func(*Context, *Value) *Value - -type BuiltInConstructor struct { - Constructor - callback ConstructorCallBack -} - -func (c *BuiltInConstructor) Construct(context *Context, _ *Plasma, object *Value) *Value { - return c.callback(context, object) -} - -func NewBuiltInConstructor(callback ConstructorCallBack) *BuiltInConstructor { - return &BuiltInConstructor{ - callback: callback, - } -} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/vm/context.go b/vendor/github.com/shoriwe/gplasma/pkg/vm/context.go index e7ca808..96ad582 100644 --- a/vendor/github.com/shoriwe/gplasma/pkg/vm/context.go +++ b/vendor/github.com/shoriwe/gplasma/pkg/vm/context.go @@ -1,51 +1,52 @@ package vm -type Context struct { - ObjectStack *ObjectStack - SymbolStack *SymbolStack - LastObject *Value - LastState uint8 -} - -func (c *Context) PushObject(object *Value) { - c.ObjectStack.Push(object) -} -func (c *Context) PeekObject() *Value { - return c.ObjectStack.Peek() -} - -func (c *Context) PopObject() *Value { - return c.ObjectStack.Pop() -} - -func (c *Context) PushSymbolTable(table *SymbolTable) { - c.SymbolStack.Push(table) -} - -func (c *Context) PopSymbolTable() *SymbolTable { - return c.SymbolStack.Pop() -} - -func (c *Context) PeekSymbolTable() *SymbolTable { - return c.SymbolStack.Peek() -} - -func (c *Context) ReturnState() { - c.LastState = ReturnState -} - -func (c *Context) BreakState() { - c.LastState = BreakState -} - -func (c *Context) RedoState() { - c.LastState = RedoState -} - -func (c *Context) ContinueState() { - c.LastState = ContinueState -} - -func (c *Context) NoState() { - c.LastState = NoState +import ( + "github.com/shoriwe/gplasma/pkg/common" +) + +type ( + contextCode struct { + bytecode []byte + rip int64 + onExit *common.ListStack[[]byte] + } + context struct { + result chan *Value + err chan error + stop chan struct{} + code *common.ListStack[*contextCode] + stack *common.ListStack[*Value] + register *Value + currentSymbols *Symbols + } +) + +func (ctx *context) hasNext() bool { + for ctx.code.HasNext() { + ctxCode := ctx.code.Peek() + if ctxCode.rip >= int64(len(ctxCode.bytecode)) { + ctx.popCode() + continue + } + return true + } + return false +} + +func (plasma *Plasma) newContext(bytecode []byte) *context { + codeStack := &common.ListStack[*contextCode]{} + codeStack.Push(&contextCode{ + bytecode: bytecode, + rip: 0, + onExit: &common.ListStack[[]byte]{}, + }) + return &context{ + result: nil, + err: nil, + stop: nil, + code: codeStack, + stack: &common.ListStack[*Value]{}, + register: nil, + currentSymbols: plasma.rootSymbols, + } } diff --git a/vendor/github.com/shoriwe/gplasma/pkg/vm/debug.go b/vendor/github.com/shoriwe/gplasma/pkg/vm/debug.go new file mode 100644 index 0000000..962cf6b --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/vm/debug.go @@ -0,0 +1,11 @@ +package vm + +import "fmt" + +func (plasma *Plasma) printStack(ctx *context) { + current := ctx.stack.Top + for current != nil { + fmt.Println("\t", current.Value.(*Value).TypeId(), current.Value) + current = current.Next + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/vm/default.go b/vendor/github.com/shoriwe/gplasma/pkg/vm/default.go deleted file mode 100644 index 42ab5d4..0000000 --- a/vendor/github.com/shoriwe/gplasma/pkg/vm/default.go +++ /dev/null @@ -1,824 +0,0 @@ -package vm - -import ( - "fmt" -) - -/* - Type - (Done) - Function - (Done) - Value - (Done) - Bool - (Done) - Bytes - (Done) - String - (Done) - HashTable - (Done) - Integer - (Done) - Array - (Done) - Tuple - (Done) - Hash - (Done) - Expand - (Done) - Id - (Done) - Range - (Done) - Len - (Done) - DeleteFrom - (Done) - Dir - (Done) - Input - (Done) - ToString - (Done) - ToTuple - (Done) - ToArray - (Done) - ToInteger - (Done) - ToFloat - (Done) - ToBool - (Done) -*/ -func (p *Plasma) InitializeBuiltIn() { - if !p.BuiltInContext.SymbolStack.HasNext() { - - } - /* - This is the master symbol table that is protected from writes - */ - - // Types - p.BuiltInContext.PeekSymbolTable().Set(TypeName, p.NewType(p.BuiltInContext, true, TypeName, nil, nil, NewBuiltInConstructor(p.ObjectInitialize(true)))) - //// Default Error Types - exception := p.NewType(p.BuiltInContext, true, RuntimeError, p.BuiltInContext.PeekSymbolTable(), nil, - NewBuiltInConstructor(p.RuntimeErrorInitialize), - ) - p.BuiltInContext.PeekSymbolTable().Set(RuntimeError, exception) - p.BuiltInContext.PeekSymbolTable().Set(InvalidTypeError, - p.NewType(p.BuiltInContext, true, InvalidTypeError, p.BuiltInContext.PeekSymbolTable(), []*Value{exception}, - NewBuiltInConstructor( - func(context *Context, object *Value) *Value { - object.SetOnDemandSymbol(Initialize, - func() *Value { - return p.NewFunction(context, true, object.SymbolTable(), - NewBuiltInClassFunction(object, 2, - func(self *Value, arguments ...*Value) (*Value, bool) { - received := arguments[0] - if !received.IsTypeById(StringId) { - return p.NewInvalidTypeError(context, received.TypeName(), StringName), false - } - expecting := arguments[1] - if !expecting.IsTypeById(StringId) { - return p.NewInvalidTypeError(context, expecting.TypeName(), StringName), false - } - self.String = fmt.Sprintf("Expecting %s but received %s", expecting.String, received.String) - return p.GetNone(), true - }, - ), - ) - }, - ) - return nil - }, - ), - ), - ) - p.BuiltInContext.PeekSymbolTable().Set(NotImplementedCallableError, - p.NewType(p.BuiltInContext, true, NotImplementedCallableError, p.BuiltInContext.PeekSymbolTable(), []*Value{exception}, - NewBuiltInConstructor( - func(context *Context, object *Value) *Value { - object.SetOnDemandSymbol(Initialize, - func() *Value { - return p.NewFunction(context, true, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - methodNameObject := arguments[0] - methodNameObjectToString, getError := methodNameObject.Get(p, context, ToString) - if getError != nil { - return getError, false - } - methodNameString, success := p.CallFunction(context, methodNameObjectToString) - if !success { - return methodNameString, false - } - if !methodNameString.IsTypeById(StringId) { - return p.NewInvalidTypeError(context, methodNameString.TypeName(), StringName), false - } - self.String = fmt.Sprintf("Method %s not implemented", methodNameString.String) - return p.GetNone(), true - }, - ), - ) - }, - ) - return nil - }, - ), - ), - ) - p.BuiltInContext.PeekSymbolTable().Set(ObjectConstructionError, - p.NewType(p.BuiltInContext, true, ObjectConstructionError, p.BuiltInContext.PeekSymbolTable(), []*Value{exception}, - NewBuiltInConstructor( - func(context *Context, object *Value) *Value { - object.SetOnDemandSymbol(Initialize, - func() *Value { - return p.NewFunction(context, true, object.SymbolTable(), - NewBuiltInClassFunction(object, 2, - func(self *Value, arguments ...*Value) (*Value, bool) { - typeName := arguments[0] - if !typeName.IsTypeById(StringId) { - return p.NewInvalidTypeError(context, typeName.TypeName(), StringName), false - } - errorMessage := arguments[1] - if !typeName.IsTypeById(StringId) { - return p.NewInvalidTypeError(context, errorMessage.TypeName(), StringName), false - } - self.String = fmt.Sprintf("Could not construct object of Type: %s -> %s", typeName.String, errorMessage.String) - return p.GetNone(), true - }, - ), - ) - }, - ) - return nil - }, - ), - ), - ) - p.BuiltInContext.PeekSymbolTable().Set(ObjectWithNameNotFoundError, - p.NewType(p.BuiltInContext, true, ObjectWithNameNotFoundError, p.BuiltInContext.PeekSymbolTable(), []*Value{exception}, - NewBuiltInConstructor( - func(context *Context, object *Value) *Value { - object.SetOnDemandSymbol(Initialize, - func() *Value { - return p.NewFunction(context, true, object.SymbolTable(), - NewBuiltInClassFunction(object, 2, - func(self *Value, arguments ...*Value) (*Value, bool) { - objectType := arguments[0] - if !objectType.IsTypeById(TypeId) { - return p.NewInvalidTypeError(context, objectType.TypeName(), TypeName), false - } - name := arguments[1] - if !name.IsTypeById(StringId) { - return p.NewInvalidTypeError(context, name.TypeName(), StringName), false - } - self.String = fmt.Sprintf(" Value with name %s not Found inside object of type %s", name.String, objectType.Name) - return p.GetNone(), true - }, - ), - ) - }, - ) - return nil - }, - ), - ), - ) - - p.BuiltInContext.PeekSymbolTable().Set(InvalidNumberOfArgumentsError, - p.NewType(p.BuiltInContext, true, InvalidNumberOfArgumentsError, p.BuiltInContext.PeekSymbolTable(), []*Value{exception}, - NewBuiltInConstructor( - func(context *Context, object *Value) *Value { - object.SetOnDemandSymbol(Initialize, - func() *Value { - return p.NewFunction(context, true, object.SymbolTable(), - NewBuiltInClassFunction(object, 2, - func(self *Value, arguments ...*Value) (*Value, bool) { - received := arguments[0] - if !received.IsTypeById(IntegerId) { - return p.NewInvalidTypeError(context, received.TypeName(), IntegerName), false - } - expecting := arguments[1] - if !expecting.IsTypeById(IntegerId) { - return p.NewInvalidTypeError(context, expecting.TypeName(), IntegerName), false - } - self.String = fmt.Sprintf("Received %d but expecting %d expecting", received.Integer, expecting.Integer) - return p.GetNone(), true - }, - ), - ) - }, - ) - return nil - }, - ), - ), - ) - p.BuiltInContext.PeekSymbolTable().Set(GoRuntimeError, - p.NewType(p.BuiltInContext, true, GoRuntimeError, p.BuiltInContext.PeekSymbolTable(), []*Value{exception}, - NewBuiltInConstructor( - func(context *Context, object *Value) *Value { - object.SetOnDemandSymbol(Initialize, - func() *Value { - return p.NewFunction(context, true, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - runtimeError := arguments[0] - if !runtimeError.IsTypeById(StringId) { - return p.NewInvalidTypeError(context, runtimeError.TypeName(), StringName), false - } - self.String = runtimeError.String - return p.GetNone(), true - }, - ), - ) - }, - ) - return nil - }, - ), - ), - ) - p.BuiltInContext.PeekSymbolTable().Set(UnhashableTypeError, - p.NewType(p.BuiltInContext, true, UnhashableTypeError, p.BuiltInContext.PeekSymbolTable(), []*Value{exception}, - NewBuiltInConstructor( - func(context *Context, object *Value) *Value { - object.SetOnDemandSymbol(Initialize, - func() *Value { - return p.NewFunction(context, true, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - objectType := arguments[0] - if !objectType.IsTypeById(TypeId) { - return p.NewInvalidTypeError(context, objectType.TypeName(), TypeName), false - } - self.String = fmt.Sprintf(" Value of type: %s is unhasable", objectType.Name) - return p.GetNone(), true - }, - ), - ) - }, - ) - return nil - }, - ), - ), - ) - p.BuiltInContext.PeekSymbolTable().Set(IndexOutOfRangeError, - p.NewType(p.BuiltInContext, true, IndexOutOfRangeError, p.BuiltInContext.PeekSymbolTable(), []*Value{exception}, - NewBuiltInConstructor( - func(context *Context, object *Value) *Value { - object.SetOnDemandSymbol(Initialize, - func() *Value { - return p.NewFunction(context, true, object.SymbolTable(), - NewBuiltInClassFunction(object, 2, - func(self *Value, arguments ...*Value) (*Value, bool) { - length := arguments[0] - if !length.IsTypeById(IntegerId) { - return p.NewInvalidTypeError(context, length.TypeName(), IntegerName), false - } - index := arguments[1] - if !index.IsTypeById(IntegerId) { - return p.NewInvalidTypeError(context, index.TypeName(), IntegerName), false - } - self.String = fmt.Sprintf("Index: %d, out of range (Length=%d)", index.Integer, length.Integer) - return p.GetNone(), true - }, - ), - ) - }, - ) - return nil - }, - ), - ), - ) - p.BuiltInContext.PeekSymbolTable().Set(KeyNotFoundError, - p.NewType(p.BuiltInContext, true, KeyNotFoundError, p.BuiltInContext.PeekSymbolTable(), []*Value{exception}, - NewBuiltInConstructor( - func(context *Context, object *Value) *Value { - object.SetOnDemandSymbol(Initialize, - func() *Value { - return p.NewFunction(context, true, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - key := arguments[0] - keyToString, getError := key.Get(p, context, ToString) - if getError != nil { - return getError, false - } - keyString, success := p.CallFunction(context, keyToString) - if !success { - return keyString, false - } - if !keyString.IsTypeById(StringId) { - return p.NewInvalidTypeError(context, keyString.TypeName(), StringName), false - } - self.String = fmt.Sprintf("Key %s not found", keyString.String) - return p.GetNone(), true - }, - ), - ) - }, - ) - return nil - }, - ), - ), - ) - p.BuiltInContext.PeekSymbolTable().Set(IntegerParsingError, - p.NewType(p.BuiltInContext, true, IntegerParsingError, p.BuiltInContext.PeekSymbolTable(), []*Value{exception}, - NewBuiltInConstructor( - func(context *Context, object *Value) *Value { - object.SetOnDemandSymbol(Initialize, - func() *Value { - return p.NewFunction(context, true, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, arguments ...*Value) (*Value, bool) { - self.String = "Integer parsing error" - return p.GetNone(), true - }, - ), - ) - }, - ) - return nil - }, - ), - ), - ) - p.BuiltInContext.PeekSymbolTable().Set(FloatParsingError, - p.NewType(p.BuiltInContext, true, FloatParsingError, p.BuiltInContext.PeekSymbolTable(), []*Value{exception}, - NewBuiltInConstructor( - func(context *Context, object *Value) *Value { - object.SetOnDemandSymbol(Initialize, - func() *Value { - return p.NewFunction(context, true, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, arguments ...*Value) (*Value, bool) { - self.String = "Float parsing error" - return p.GetNone(), true - }, - ), - ) - }, - ) - return nil - }, - ), - ), - ) - p.BuiltInContext.PeekSymbolTable().Set(BuiltInSymbolProtectionError, - p.NewType(p.BuiltInContext, true, BuiltInSymbolProtectionError, p.BuiltInContext.PeekSymbolTable(), []*Value{exception}, - NewBuiltInConstructor( - func(context *Context, object *Value) *Value { - object.SetOnDemandSymbol(Initialize, - func() *Value { - return p.NewFunction(context, true, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - symbolName := arguments[0] - if !symbolName.IsTypeById(StringId) { - return p.NewInvalidTypeError(context, symbolName.TypeName(), StringName), false - } - self.String = fmt.Sprintf("cannot assign/delete built-in symbol %s", symbolName.String) - return p.GetNone(), true - }, - ), - ) - }, - ) - return nil - }, - ), - ), - ) - p.BuiltInContext.PeekSymbolTable().Set(ObjectNotCallableError, - p.NewType(p.BuiltInContext, true, ObjectNotCallableError, p.BuiltInContext.PeekSymbolTable(), []*Value{exception}, - NewBuiltInConstructor( - func(context *Context, object *Value) *Value { - object.SetOnDemandSymbol(Initialize, - func() *Value { - return p.NewFunction(context, true, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - receivedType := arguments[0] - if !receivedType.IsTypeById(TypeId) { - return p.NewInvalidTypeError(context, receivedType.TypeName(), TypeName), false - } - self.String = fmt.Sprintf(" Value of type %s object is not callable", receivedType.Name) - return p.GetNone(), true - }, - ), - ) - }, - ) - return nil - }, - ), - ), - ) - //// Default Types - p.BuiltInContext.PeekSymbolTable().Set(CallableName, - p.NewType(p.BuiltInContext, true, CallableName, p.BuiltInContext.PeekSymbolTable(), nil, - NewBuiltInConstructor(p.CallableInitialize(false)), - ), - ) - p.BuiltInContext.PeekSymbolTable().Set(NoneName, - p.NewType(p.BuiltInContext, true, NoneName, p.BuiltInContext.PeekSymbolTable(), nil, - NewBuiltInConstructor(p.NoneInitialize(false)), - ), - ) - p.BuiltInContext.PeekSymbolTable().Set(ModuleName, - p.NewType(p.BuiltInContext, true, ModuleName, p.BuiltInContext.PeekSymbolTable(), nil, - NewBuiltInConstructor(p.ObjectInitialize(false)), - ), - ) - p.BuiltInContext.PeekSymbolTable().Set(BoolName, - p.NewType(p.BuiltInContext, true, BoolName, p.BuiltInContext.PeekSymbolTable(), nil, - NewBuiltInConstructor(p.BoolInitialize(false)), - ), - ) - p.BuiltInContext.PeekSymbolTable().Set(IteratorName, - p.NewType(p.BuiltInContext, true, IteratorName, p.BuiltInContext.PeekSymbolTable(), nil, - NewBuiltInConstructor(p.IteratorInitialize(false)), - ), - ) - p.BuiltInContext.PeekSymbolTable().Set(FloatName, - p.NewType(p.BuiltInContext, true, FloatName, p.BuiltInContext.PeekSymbolTable(), nil, - NewBuiltInConstructor(p.FloatInitialize(false)), - ), - ) - p.BuiltInContext.PeekSymbolTable().Set(ValueName, - p.NewType(p.BuiltInContext, true, ValueName, - nil, nil, - NewBuiltInConstructor(p.ObjectInitialize(false)), - ), - ) - p.BuiltInContext.PeekSymbolTable().Set(FunctionName, - p.NewType(p.BuiltInContext, true, FunctionName, p.BuiltInContext.PeekSymbolTable(), nil, - NewBuiltInConstructor(p.ObjectInitialize(false)), - ), - ) - p.BuiltInContext.PeekSymbolTable().Set(IntegerName, - p.NewType(p.BuiltInContext, true, IntegerName, p.BuiltInContext.PeekSymbolTable(), nil, - NewBuiltInConstructor(p.IntegerInitialize(false)), - ), - ) - p.BuiltInContext.PeekSymbolTable().Set(StringName, - p.NewType(p.BuiltInContext, true, StringName, p.BuiltInContext.PeekSymbolTable(), nil, - NewBuiltInConstructor(p.StringInitialize(false)), - ), - ) - p.BuiltInContext.PeekSymbolTable().Set(BytesName, - p.NewType(p.BuiltInContext, true, BytesName, p.BuiltInContext.PeekSymbolTable(), nil, - NewBuiltInConstructor(p.BytesInitialize(false)), - ), - ) - p.BuiltInContext.PeekSymbolTable().Set(TupleName, - p.NewType(p.BuiltInContext, true, TupleName, p.BuiltInContext.PeekSymbolTable(), nil, - NewBuiltInConstructor(p.TupleInitialize(false)), - ), - ) - p.BuiltInContext.PeekSymbolTable().Set(ArrayName, - p.NewType(p.BuiltInContext, true, ArrayName, p.BuiltInContext.PeekSymbolTable(), nil, - NewBuiltInConstructor(p.ArrayInitialize(false)), - ), - ) - p.BuiltInContext.PeekSymbolTable().Set(HashName, - p.NewType(p.BuiltInContext, true, HashName, p.BuiltInContext.PeekSymbolTable(), nil, - NewBuiltInConstructor(p.HashTableInitialize(false)), - ), - ) - // Names - p.BuiltInContext.PeekSymbolTable().Set(TrueName, p.NewBool(p.BuiltInContext, true, true)) - p.BuiltInContext.PeekSymbolTable().Set(FalseName, p.NewBool(p.BuiltInContext, true, false)) - p.BuiltInContext.PeekSymbolTable().Set(None, p.NewNone(p.BuiltInContext, true, p.BuiltInContext.PeekSymbolTable())) - // Functions - p.BuiltInContext.PeekSymbolTable().Set("expand", - p.NewFunction(p.BuiltInContext, true, p.BuiltInContext.PeekSymbolTable(), - NewBuiltInFunction(2, - func(_ *Value, arguments ...*Value) (*Value, bool) { - receiver := arguments[0] - for symbol, object := range arguments[1].SymbolTable().Symbols { - receiver.Set(p, p.BuiltInContext, symbol, object) - } - return p.GetNone(), true - }, - ), - ), - ) - p.BuiltInContext.PeekSymbolTable().Set("dir", - p.NewFunction(p.BuiltInContext, true, p.BuiltInContext.PeekSymbolTable(), - NewBuiltInFunction(1, - func(_ *Value, arguments ...*Value) (*Value, bool) { - object := arguments[0] - var symbols []*Value - for symbol := range object.Dir() { - symbols = append(symbols, p.NewString(p.BuiltInContext, false, symbol)) - } - return p.NewTuple(p.BuiltInContext, false, symbols), true - }, - ), - ), - ) - p.BuiltInContext.PeekSymbolTable().Set("set", - p.NewFunction(p.BuiltInContext, true, p.BuiltInContext.PeekSymbolTable(), - NewBuiltInFunction(3, - func(_ *Value, arguments ...*Value) (*Value, bool) { - source := arguments[0] - symbol := arguments[1] - value := arguments[2] - if !symbol.IsTypeById(StringId) { - return p.NewInvalidTypeError(p.BuiltInContext, symbol.TypeName(), StringName), false - } - if source.IsBuiltIn { - return p.NewBuiltInSymbolProtectionError(p.BuiltInContext, symbol.String), false - } - source.Set(p, p.BuiltInContext, symbol.String, value) - return p.GetNone(), true - }, - ), - ), - ) - p.BuiltInContext.PeekSymbolTable().Set("get_from", - p.NewFunction(p.BuiltInContext, true, p.BuiltInContext.PeekSymbolTable(), - NewBuiltInFunction(2, - func(_ *Value, arguments ...*Value) (*Value, bool) { - source := arguments[0] - symbol := arguments[1] - if !symbol.IsTypeById(StringId) { - return p.NewInvalidTypeError(p.BuiltInContext, symbol.TypeName(), StringName), false - } - value, getError := source.Get(p, p.BuiltInContext, symbol.String) - if getError != nil { - return getError, false - } - return value, true - }, - ), - ), - ) - p.BuiltInContext.PeekSymbolTable().Set("delete_from", - p.NewFunction(p.BuiltInContext, true, p.BuiltInContext.PeekSymbolTable(), - NewBuiltInFunction(2, - func(_ *Value, arguments ...*Value) (*Value, bool) { - source := arguments[0] - symbol := arguments[1] - if !symbol.IsTypeById(StringId) { - return p.NewInvalidTypeError(p.BuiltInContext, symbol.TypeName(), StringName), false - } - if source.IsBuiltIn { - return p.NewBuiltInSymbolProtectionError(p.BuiltInContext, symbol.String), false - } - _, getError := source.SymbolTable().GetSelf(symbol.String) - if getError != nil { - return p.NewObjectWithNameNotFoundError(p.BuiltInContext, source.GetClass(p), symbol.String), false - } - delete(source.SymbolTable().Symbols, symbol.String) - return p.GetNone(), true - }, - ), - ), - ) - p.BuiltInContext.PeekSymbolTable().Set("input", - p.NewFunction(p.BuiltInContext, true, p.BuiltInContext.PeekSymbolTable(), - NewBuiltInFunction(1, - func(_ *Value, arguments ...*Value) (*Value, bool) { - message := arguments[0] - var messageString *Value - if !message.IsTypeById(StringId) { - messageToString, getError := message.Get(p, p.BuiltInContext, ToString) - if getError != nil { - return getError, false - } - toStringResult, success := p.CallFunction(p.BuiltInContext, messageToString) - if !success { - return toStringResult, false - } - if !toStringResult.IsTypeById(StringId) { - return p.NewInvalidTypeError(p.BuiltInContext, toStringResult.TypeName(), StringName), false - } - messageString = toStringResult - } else { - messageString = message - } - _, writingError := p.StdOut().Write([]byte(messageString.String)) - if writingError != nil { - return p.NewGoRuntimeError(p.BuiltInContext, writingError), false - } - if p.StdInScanner().Scan() { - return p.NewString(p.BuiltInContext, false, p.StdInScanner().Text()), true - } - return p.NewGoRuntimeError(p.BuiltInContext, p.StdInScanner().Err()), false - }, - ), - ), - ) - p.BuiltInContext.PeekSymbolTable().Set("print", - p.NewFunction(p.BuiltInContext, true, p.BuiltInContext.PeekSymbolTable(), - NewBuiltInFunction(1, - func(_ *Value, arguments ...*Value) (*Value, bool) { - value := arguments[0] - toString, getError := value.Get(p, p.BuiltInContext, ToString) - if getError != nil { - return getError, false - } - stringValue, success := p.CallFunction(p.BuiltInContext, toString) - if !success { - return stringValue, false - } - _, writeError := fmt.Fprintf(p.StdOut(), "%s", stringValue.String) - if writeError != nil { - return p.NewGoRuntimeError(p.BuiltInContext, writeError), false - } - return p.GetNone(), true - }, - ), - ), - ) - p.BuiltInContext.PeekSymbolTable().Set("println", - p.NewFunction(p.BuiltInContext, true, p.BuiltInContext.PeekSymbolTable(), - NewBuiltInFunction(1, - func(_ *Value, arguments ...*Value) (*Value, bool) { - value := arguments[0] - toString, getError := value.Get(p, p.BuiltInContext, ToString) - if getError != nil { - return getError, false - } - stringValue, success := p.CallFunction(p.BuiltInContext, toString) - if !success { - return stringValue, false - } - _, writeError := fmt.Fprintf(p.StdOut(), "%s\n", stringValue.String) - if writeError != nil { - return p.NewGoRuntimeError(p.BuiltInContext, writeError), false - } - return p.GetNone(), true - }, - ), - ), - ) - p.BuiltInContext.PeekSymbolTable().Set("id", - p.NewFunction(p.BuiltInContext, true, p.BuiltInContext.PeekSymbolTable(), - NewBuiltInFunction(1, - func(_ *Value, arguments ...*Value) (*Value, bool) { - object := arguments[0] - return p.NewInteger(p.BuiltInContext, false, object.Id()), true - }, - ), - ), - ) - p.BuiltInContext.PeekSymbolTable().Set("range", - p.NewFunction(p.BuiltInContext, true, p.BuiltInContext.PeekSymbolTable(), - NewBuiltInFunction(3, - func(_ *Value, arguments ...*Value) (*Value, bool) { - start := arguments[0] - if !start.IsTypeById(IntegerId) { - return p.NewInvalidTypeError(p.BuiltInContext, start.TypeName(), IntegerName), false - } - - end := arguments[1] - if !end.IsTypeById(IntegerId) { - return p.NewInvalidTypeError(p.BuiltInContext, end.TypeName(), IntegerName), false - } - - step := arguments[2] - if !step.IsTypeById(IntegerId) { - return p.NewInvalidTypeError(p.BuiltInContext, step.TypeName(), IntegerName), false - } - - rangeInformation := struct { - current int64 - end int64 - step int64 - }{ - current: start.Integer, - end: end.Integer, - step: step.Integer, - } - - // This should return a iterator - rangeIterator := p.NewIterator(p.BuiltInContext, false) - - rangeIterator.Set(p, p.BuiltInContext, HasNext, - p.NewFunction(p.BuiltInContext, true, rangeIterator.SymbolTable(), - NewBuiltInClassFunction(rangeIterator, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - if rangeInformation.current < rangeInformation.end { - return p.GetTrue(), true - } - return p.GetFalse(), true - }, - ), - ), - ) - rangeIterator.Set(p, p.BuiltInContext, Next, - p.NewFunction(p.BuiltInContext, true, rangeIterator.SymbolTable(), - NewBuiltInClassFunction(rangeIterator, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - number := rangeInformation.current - rangeInformation.current += rangeInformation.step - return p.NewInteger(p.BuiltInContext, false, number), true - }, - ), - ), - ) - return rangeIterator, true - }, - ), - ), - ) - p.BuiltInContext.PeekSymbolTable().Set("super", - p.NewFunction(p.BuiltInContext, true, p.BuiltInContext.PeekSymbolTable(), - NewBuiltInFunction(2, - func(_ *Value, arguments ...*Value) (*Value, bool) { - return p.NewProxyObject(p.BuiltInContext, arguments[0], arguments[1]) - }, - ), - ), - ) - p.BuiltInContext.PeekSymbolTable().Set("map", - p.NewFunction(p.BuiltInContext, true, p.BuiltInContext.PeekSymbolTable(), - NewBuiltInFunction(2, - func(_ *Value, arguments ...*Value) (*Value, bool) { - asIterator, interpretationSuccess := p.InterpretAsIterator(p.BuiltInContext, arguments[1]) - if !interpretationSuccess { - return asIterator, false - } - hasNext, hasNextGetError := asIterator.Get(p, p.BuiltInContext, HasNext) - if hasNextGetError != nil { - return hasNextGetError, false - } - next, nextGetError := asIterator.Get(p, p.BuiltInContext, Next) - if nextGetError != nil { - return nextGetError, false - } - result := p.NewIterator(p.BuiltInContext, false) - - // Set Next - result.Set(p, p.BuiltInContext, Next, - p.NewFunction(p.BuiltInContext, false, result.symbols, - NewBuiltInClassFunction(result, 0, - func(value *Value, value2 ...*Value) (*Value, bool) { - nextValue, success := p.CallFunction(p.BuiltInContext, next) - if !success { - return nextValue, false - } - return p.CallFunction(p.BuiltInContext, arguments[0], nextValue) - }, - ), - ), - ) - - // Set HasNext - result.Set(p, p.BuiltInContext, HasNext, hasNext) - - return result, true - }, - ), - ), - ) - p.BuiltInContext.PeekSymbolTable().Set("filter", - p.NewFunction(p.BuiltInContext, true, p.BuiltInContext.PeekSymbolTable(), - NewBuiltInFunction(2, - func(_ *Value, arguments ...*Value) (*Value, bool) { - asIterator, interpretationSuccess := p.InterpretAsIterator(p.BuiltInContext, arguments[1]) - if !interpretationSuccess { - return asIterator, false - } - hasNext, hasNextGetError := asIterator.Get(p, p.BuiltInContext, HasNext) - if hasNextGetError != nil { - return hasNextGetError, false - } - next, nextGetError := asIterator.Get(p, p.BuiltInContext, Next) - if nextGetError != nil { - return nextGetError, false - } - result := p.NewIterator(p.BuiltInContext, false) - - // Set Next - result.Set(p, p.BuiltInContext, Next, - p.NewFunction(p.BuiltInContext, false, result.symbols, - NewBuiltInClassFunction(result, 0, - func(value *Value, value2 ...*Value) (*Value, bool) { - var ( - nextValue *Value - filterResult *Value - ) - for { - doesHasNext, success := p.CallFunction(p.BuiltInContext, hasNext) - if !success { - return doesHasNext, false - } - nextValue, success = p.CallFunction(p.BuiltInContext, next) - if !success { - return nextValue, false - } - filterResult, success = p.CallFunction(p.BuiltInContext, arguments[0], nextValue) - if !success { - return filterResult, false - } - asBool, interpretationError := p.QuickGetBool(p.BuiltInContext, filterResult) - if interpretationError != nil { - return interpretationError, false - } - if asBool { - return nextValue, true - } - } - }, - ), - ), - ) - - // Set HasNext - result.Set(p, p.BuiltInContext, HasNext, hasNext) - - return result, true - }, - ), - ), - ) -} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/vm/do.go b/vendor/github.com/shoriwe/gplasma/pkg/vm/do.go new file mode 100644 index 0000000..77a7b98 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/vm/do.go @@ -0,0 +1,344 @@ +package vm + +import ( + "fmt" + "github.com/shoriwe/gplasma/pkg/bytecode/opcodes" + "github.com/shoriwe/gplasma/pkg/common" + magic_functions "github.com/shoriwe/gplasma/pkg/common/magic-functions" + special_symbols "github.com/shoriwe/gplasma/pkg/common/special-symbols" +) + +func (ctx *context) pushCode(bytecode []byte) { + ctx.code.Push( + &contextCode{ + bytecode: bytecode, + rip: 0, + onExit: &common.ListStack[[]byte]{}, + }, + ) +} +func (ctx *context) popCode() { + // If there is defer code + if ctxCode := ctx.code.Peek(); ctxCode.onExit.HasNext() { + ctxCode.rip = int64(len(ctxCode.bytecode)) + 1 + if ctx.register != nil { + ctx.stack.Push(ctx.register) + ctx.pushCode([]byte{opcodes.Return}) + ctx.currentSymbols = NewSymbols(ctx.currentSymbols) + } + for ctxCode.onExit.HasNext() { + ctx.pushCode(ctxCode.onExit.Pop()) + ctx.currentSymbols = NewSymbols(ctx.currentSymbols) + } + return + } + ctx.code.Pop() + if ctx.currentSymbols.call != nil { + ctx.currentSymbols = ctx.currentSymbols.call + } else { + ctx.currentSymbols = ctx.currentSymbols.Parent + } +} + +func (plasma *Plasma) prepareClassInitCode(classInfo *ClassInfo) { + var result []byte + for _, base := range classInfo.Bases { + if base.TypeId() != ClassId { + panic("no type received as base for class") + } + baseClassInfo := base.GetClassInfo() + if !baseClassInfo.prepared { + plasma.prepareClassInitCode(baseClassInfo) + } + result = append(result, baseClassInfo.Bytecode...) + } + result = append(result, classInfo.Bytecode...) + classInfo.prepared = true + classInfo.Bytecode = result +} + +func (plasma *Plasma) do(ctx *context) { + ctxCode := ctx.code.Peek() + instruction := ctxCode.bytecode[ctxCode.rip] + // fmt.Println(opcodes.OpCodes[instruction]) + // plasma.printStack(ctx) + switch instruction { + case opcodes.Push: + ctxCode.rip++ + ctx.stack.Push(ctx.register) + case opcodes.Pop: + ctxCode.rip++ + ctx.register = ctx.stack.Pop() + case opcodes.IdentifierAssign: + ctxCode.rip++ + symbolLength := common.BytesToInt(ctxCode.bytecode[ctxCode.rip : ctxCode.rip+8]) + ctxCode.rip += 8 + symbol := string(ctxCode.bytecode[ctxCode.rip : ctxCode.rip+symbolLength]) + // fmt.Println(symbol) + ctxCode.rip += symbolLength + ctx.currentSymbols.Set(symbol, ctx.stack.Pop()) + case opcodes.SelectorAssign: + ctxCode.rip++ + symbolLength := common.BytesToInt(ctxCode.bytecode[ctxCode.rip : ctxCode.rip+8]) + ctxCode.rip += 8 + symbol := string(ctxCode.bytecode[ctxCode.rip : ctxCode.rip+symbolLength]) + ctxCode.rip += symbolLength + selector := ctx.stack.Pop() + selector.Set(symbol, ctx.stack.Pop()) + case opcodes.Label: + ctxCode.rip += 9 // OP + Label + case opcodes.Jump: + ctxCode.rip += common.BytesToInt(ctxCode.bytecode[1+ctxCode.rip : 9+ctxCode.rip]) + case opcodes.IfJump: + if ctx.stack.Pop().Bool() { + ctxCode.rip += common.BytesToInt(ctxCode.bytecode[1+ctxCode.rip : 9+ctxCode.rip]) + } else { + ctxCode.rip += 9 + } + case opcodes.Return: + ctxCode.rip++ + ctx.register = ctx.stack.Pop() + ctx.popCode() + case opcodes.DeleteIdentifier: + ctxCode.rip++ + symbolLength := common.BytesToInt(ctxCode.bytecode[ctxCode.rip : ctxCode.rip+8]) + ctxCode.rip += 8 + symbol := string(ctxCode.bytecode[ctxCode.rip : ctxCode.rip+symbolLength]) + ctxCode.rip += symbolLength + delError := ctx.currentSymbols.Del(symbol) + if delError != nil { + panic(delError) + } + case opcodes.DeleteSelector: + ctxCode.rip++ + symbolLength := common.BytesToInt(ctxCode.bytecode[ctxCode.rip : ctxCode.rip+8]) + ctxCode.rip += 8 + symbol := string(ctxCode.bytecode[ctxCode.rip : ctxCode.rip+symbolLength]) + ctxCode.rip += symbolLength + selector := ctx.stack.Pop() + delError := selector.Del(symbol) + if delError != nil { + panic(delError) + } + case opcodes.Defer: + ctxCode.rip++ + exprLength := common.BytesToInt(ctxCode.bytecode[ctxCode.rip : ctxCode.rip+8]) + ctxCode.rip += 8 + onExitCode := ctxCode.bytecode[ctxCode.rip : ctxCode.rip+exprLength] + ctxCode.rip += exprLength + ctxCode.onExit.Push(onExitCode) + case opcodes.NewFunction: + ctxCode.rip++ + numberOfArgument := common.BytesToInt(ctxCode.bytecode[ctxCode.rip : ctxCode.rip+8]) + ctxCode.rip += 8 + arguments := make([]string, 0, numberOfArgument) + for i := int64(0); i < numberOfArgument; i++ { + symbolLength := common.BytesToInt(ctxCode.bytecode[ctxCode.rip : ctxCode.rip+8]) + ctxCode.rip += 8 + symbol := string(ctxCode.bytecode[ctxCode.rip : ctxCode.rip+symbolLength]) + ctxCode.rip += symbolLength + arguments = append(arguments, symbol) + } + bytecodeLength := common.BytesToInt(ctxCode.bytecode[ctxCode.rip : ctxCode.rip+8]) + ctxCode.rip += 8 + bytecode := ctxCode.bytecode[ctxCode.rip : ctxCode.rip+bytecodeLength] + ctxCode.rip += bytecodeLength + funcInfo := FuncInfo{ + Arguments: arguments, + Bytecode: bytecode, + } + funcObject := plasma.NewValue(ctx.currentSymbols, FunctionId, plasma.function) + funcObject.SetAny(funcInfo) + ctx.register = funcObject + case opcodes.NewClass: + ctxCode.rip++ + numberOfBases := common.BytesToInt(ctxCode.bytecode[ctxCode.rip : ctxCode.rip+8]) + ctxCode.rip += 8 + bodyLength := common.BytesToInt(ctxCode.bytecode[ctxCode.rip : ctxCode.rip+8]) + ctxCode.rip += 8 + body := ctxCode.bytecode[ctxCode.rip : ctxCode.rip+bodyLength] + ctxCode.rip += bodyLength + // Get bases + bases := make([]*Value, numberOfBases) + for i := numberOfBases - 1; i >= 0; i-- { + bases[i] = ctx.stack.Pop() + } + classInfo := &ClassInfo{ + Bases: bases, + Bytecode: body, + } + classObject := plasma.NewValue(ctx.currentSymbols, ClassId, plasma.class) + classObject.SetAny(classInfo) + ctx.register = classObject + case opcodes.Call: + ctxCode.rip++ + numberOfArguments := common.BytesToInt(ctxCode.bytecode[ctxCode.rip : ctxCode.rip+8]) + ctxCode.rip += 8 + function := ctx.stack.Pop() + arguments := make([]*Value, numberOfArguments) + for i := numberOfArguments - 1; i >= 0; i-- { + arguments[i] = ctx.stack.Pop() + } + var callError error + tries := 0 + doCall: + if tries == MaxDoCallSearch { + panic("infinite nested __call__") + } + switch function.TypeId() { + case BuiltInFunctionId, BuiltInClassId: + ctx.register, callError = function.Call(arguments...) + if callError != nil { + panic(callError) + } + case FunctionId: + funcInfo := function.GetFuncInfo() + // Push new symbol table based on the function + newSymbols := NewSymbols(function.vtable) + newSymbols.call = ctx.currentSymbols + ctx.currentSymbols = newSymbols + if int64(len(funcInfo.Arguments)) != numberOfArguments { + panic("invalid number of argument for function call") + } + // Load arguments + for index, argument := range funcInfo.Arguments { + ctx.currentSymbols.Set(argument, arguments[index]) + } + // Push code + ctx.pushCode(funcInfo.Bytecode) + case ClassId: + classInfo := function.GetClassInfo() + if !classInfo.prepared { + plasma.prepareClassInitCode(classInfo) + } + // Instantiate object + object := plasma.NewValue(function.vtable, ValueId, plasma.value) + object.class = function + object.Set(special_symbols.Self, object) + // Push object + ctx.stack.Push(object) + for _, argument := range arguments { + ctx.stack.Push(argument) + } + // Push class code + classCode := make([]byte, 0, len(classInfo.Bytecode)) + classCode = append(classCode, classInfo.Bytecode...) + // inject init code: object.__init__(arguments...) + classCode = append(classCode, opcodes.Identifier) + classCode = append(classCode, common.IntToBytes(len(magic_functions.Init))...) + classCode = append(classCode, magic_functions.Init...) + classCode = append(classCode, opcodes.Push) + classCode = append(classCode, opcodes.Call) + classCode = append(classCode, common.IntToBytes(numberOfArguments)...) + // Inject pop object to register + classCode = append(classCode, opcodes.Pop) + // Load code + ctx.pushCode(classCode) + newSymbols := object.vtable + newSymbols.call = ctx.currentSymbols + ctx.currentSymbols = newSymbols + default: // __call__ + call, getError := function.Get(magic_functions.Call) + if getError != nil { + panic(getError) + } + function = call + tries++ + goto doCall + } + case opcodes.NewArray: + ctxCode.rip++ + numberOfValues := common.BytesToInt(ctxCode.bytecode[ctxCode.rip : ctxCode.rip+8]) + ctxCode.rip += 8 + values := make([]*Value, numberOfValues) + for i := numberOfValues - 1; i >= 0; i-- { + values[i] = ctx.stack.Pop() + } + ctx.register = plasma.NewArray(values) + case opcodes.NewTuple: + ctxCode.rip++ + numberOfValues := common.BytesToInt(ctxCode.bytecode[ctxCode.rip : ctxCode.rip+8]) + ctxCode.rip += 8 + values := make([]*Value, numberOfValues) + for i := numberOfValues - 1; i >= 0; i-- { + values[i] = ctx.stack.Pop() + } + ctx.register = plasma.NewTuple(values) + case opcodes.NewHash: + ctxCode.rip++ + numberOfValues := common.BytesToInt(ctxCode.bytecode[ctxCode.rip : ctxCode.rip+8]) + ctxCode.rip += 8 + hash := plasma.NewInternalHash() + for i := numberOfValues - 1; i >= 0; i-- { + key := ctx.stack.Pop() + value := ctx.stack.Pop() + setError := hash.Set(key, value) + if setError != nil { + panic(setError) + } + } + ctx.register = plasma.NewHash(hash) + case opcodes.Identifier: + ctxCode.rip++ + symbolLength := common.BytesToInt(ctxCode.bytecode[ctxCode.rip : ctxCode.rip+8]) + ctxCode.rip += 8 + symbol := string(ctxCode.bytecode[ctxCode.rip : ctxCode.rip+symbolLength]) + ctxCode.rip += symbolLength + //fmt.Println(symbol) + var getError error + ctx.register, getError = ctx.currentSymbols.Get(symbol) + if getError != nil { + panic(getError) + } + case opcodes.Integer: + ctxCode.rip++ + value := common.BytesToInt(ctxCode.bytecode[ctxCode.rip : ctxCode.rip+8]) + ctxCode.rip += 8 + ctx.register = plasma.NewInt(value) + case opcodes.Float: + ctxCode.rip++ + value := common.BytesToFloat(ctxCode.bytecode[ctxCode.rip : ctxCode.rip+8]) + ctxCode.rip += 8 + ctx.register = plasma.NewFloat(value) + case opcodes.String: + ctxCode.rip++ + stringLength := common.BytesToInt(ctxCode.bytecode[ctxCode.rip : ctxCode.rip+8]) + ctxCode.rip += 8 + contents := ctxCode.bytecode[ctxCode.rip : ctxCode.rip+stringLength] + ctxCode.rip += stringLength + ctx.register = plasma.NewString(contents) + case opcodes.Bytes: + ctxCode.rip++ + stringLength := common.BytesToInt(ctxCode.bytecode[ctxCode.rip : ctxCode.rip+8]) + ctxCode.rip += 8 + contents := ctxCode.bytecode[ctxCode.rip : ctxCode.rip+stringLength] + ctxCode.rip += stringLength + ctx.register = plasma.NewBytes(contents) + case opcodes.True: + ctxCode.rip++ + ctx.register = plasma.true + case opcodes.False: + ctxCode.rip++ + ctx.register = plasma.false + case opcodes.None: + ctxCode.rip++ + ctx.register = plasma.none + case opcodes.Selector: + ctxCode.rip++ + symbolLength := common.BytesToInt(ctxCode.bytecode[ctxCode.rip : ctxCode.rip+8]) + ctxCode.rip += 8 + symbol := string(ctxCode.bytecode[ctxCode.rip : ctxCode.rip+symbolLength]) + ctxCode.rip += symbolLength + // fmt.Println(symbol) + selector := ctx.stack.Pop() + var getError error + ctx.register, getError = selector.Get(symbol) + if getError != nil { + panic(getError) + } + case opcodes.Super: + break // TODO: Implement me! + default: + panic(fmt.Sprintf("unknown opcode %d", instruction)) + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/vm/error.go b/vendor/github.com/shoriwe/gplasma/pkg/vm/error.go deleted file mode 100644 index b6d3fb2..0000000 --- a/vendor/github.com/shoriwe/gplasma/pkg/vm/error.go +++ /dev/null @@ -1,217 +0,0 @@ -package vm - -import ( - "fmt" -) - -const ( - RuntimeError = "RuntimeError" // Done - InvalidTypeError = "InvalidTypeError" // Done - NotImplementedCallableError = "NotImplementedCallableError" // Done - ObjectConstructionError = "ObjectConstructionError" // Done - ObjectWithNameNotFoundError = "ObjectWithNameNotFoundError" // Done - InvalidNumberOfArgumentsError = "InvalidNumberOfArgumentsError" // Done - GoRuntimeError = "GoRuntimeError" // Done - UnhashableTypeError = "UnhashableTypeError" // Done - IndexOutOfRangeError = "IndexOutOfRangeError" // Done - KeyNotFoundError = "KeyNotFoundError" // Done - IntegerParsingError = "IntegerParsingError" // Done - FloatParsingError = "FloatParsingError" // Done - BuiltInSymbolProtectionError = "BuiltInSymbolProtectionError" // Done - ObjectNotCallableError = "ObjectNotCallableError" // Done -) - -func (p *Plasma) ForceGetSelf(context *Context, name string, parent *Value) *Value { - object, getError := parent.Get(p, context, name) - if getError != nil { - panic(getError) - } - return object -} - -func (p *Plasma) ForceMasterGetAny(name string) *Value { - object, getError := p.BuiltInContext.PeekSymbolTable().GetAny(name) - if getError != nil { - panic(getError.String()) - } - return object -} - -func (p *Plasma) ForceConstruction(context *Context, type_ *Value) *Value { - if !type_.IsTypeById(TypeId) { - panic("don't modify built-ins, or fatal errors like this one will ocurr") - } - result, success := p.ConstructObject(context, type_, NewSymbolTable(context.PeekSymbolTable())) - if !success { - panic(result.Name) - } - return result -} - -func (p *Plasma) ForceInitialization(context *Context, object *Value, arguments ...*Value) { - initialize, getError := object.Get(p, context, Initialize) - if getError != nil { - panic(getError) - } - callError, success := p.CallFunction(context, - initialize, - arguments..., - ) - if !success { - panic(fmt.Sprintf("%s: %s", callError.TypeName(), callError.String)) - } -} - -func (p *Plasma) NewFloatParsingError(context *Context) *Value { - errorType := p.ForceMasterGetAny(FloatParsingError) - instantiatedError := p.ForceConstruction(context, errorType) - p.ForceInitialization(context, instantiatedError) - return instantiatedError -} - -func (p *Plasma) NewIntegerParsingError(context *Context) *Value { - errorType := p.ForceMasterGetAny(IntegerParsingError) - instantiatedError := p.ForceConstruction(context, errorType) - p.ForceInitialization(context, instantiatedError) - return instantiatedError -} - -func (p *Plasma) NewKeyNotFoundError(context *Context, key *Value) *Value { - errorType := p.ForceMasterGetAny(KeyNotFoundError) - instantiatedError := p.ForceConstruction(context, errorType) - p.ForceInitialization(context, instantiatedError, - key, - ) - return instantiatedError -} - -func (p *Plasma) NewIndexOutOfRange(context *Context, length int, index int64) *Value { - errorType := p.ForceMasterGetAny(IndexOutOfRangeError) - instantiatedError := p.ForceConstruction(context, errorType) - p.ForceInitialization(context, instantiatedError, - p.NewInteger(context, false, int64(length)), - p.NewInteger(context, false, index), - ) - return instantiatedError -} - -func (p *Plasma) NewUnhashableTypeError(context *Context, objectType *Value) *Value { - errorType := p.ForceMasterGetAny(UnhashableTypeError) - instantiatedError := p.ForceConstruction(context, errorType) - p.ForceInitialization(context, instantiatedError, - objectType, - ) - return instantiatedError -} - -func (p *Plasma) NewNotImplementedCallableError(context *Context, methodName string) *Value { - errorType := p.ForceMasterGetAny(NotImplementedCallableError) - instantiatedError := p.ForceConstruction(context, errorType) - p.ForceInitialization(context, instantiatedError, - p.NewString(context, false, methodName), - ) - return instantiatedError -} - -func (p *Plasma) NewGoRuntimeError(context *Context, er error) *Value { - errorType := p.ForceMasterGetAny(GoRuntimeError) - instantiatedError := p.ForceConstruction(context, errorType) - p.ForceInitialization(context, instantiatedError, - p.NewString(context, false, er.Error()), - ) - return instantiatedError -} - -func (p *Plasma) NewInvalidNumberOfArgumentsError(context *Context, received int, expecting int) *Value { - errorType := p.ForceMasterGetAny(InvalidNumberOfArgumentsError) - instantiatedError := p.ForceConstruction(context, errorType) - p.ForceInitialization(context, instantiatedError, - p.NewInteger(context, false, int64(received)), - p.NewInteger(context, false, int64(expecting)), - ) - return instantiatedError -} - -func (p *Plasma) NewObjectWithNameNotFoundError(context *Context, objectType *Value, name string) *Value { - errorType := p.ForceMasterGetAny(ObjectWithNameNotFoundError) - instantiatedError := p.ForceConstruction(context, errorType) - p.ForceInitialization(context, instantiatedError, - objectType, p.NewString(context, false, name), - ) - return instantiatedError -} - -func (p *Plasma) NewInvalidTypeError(context *Context, received string, expecting ...string) *Value { - errorType := p.ForceMasterGetAny(InvalidTypeError) - instantiatedError := p.ForceConstruction(context, errorType) - instantiatedErrorInitialize, _ := instantiatedError.Get(p, context, Initialize) - expectingSum := "" - for index, s := range expecting { - if index != 0 { - expectingSum += ", " - } - expectingSum += s - } - _, _ = p.CallFunction(context, - instantiatedErrorInitialize, - p.NewString(context, false, received), - p.NewString(context, false, expectingSum), - ) - return instantiatedError -} - -func (p *Plasma) NewObjectConstructionError(context *Context, typeName string, errorMessage string) *Value { - errorType := p.ForceMasterGetAny(ObjectConstructionError) - instantiatedError := p.ForceConstruction(context, errorType) - p.ForceInitialization(context, instantiatedError, - p.NewString(context, false, typeName), p.NewString(context, false, errorMessage), - ) - return instantiatedError -} - -func (p *Plasma) NewBuiltInSymbolProtectionError(context *Context, symbolName string) *Value { - errorType := p.ForceMasterGetAny(BuiltInSymbolProtectionError) - instantiatedError := p.ForceConstruction(context, errorType) - p.ForceInitialization(context, instantiatedError, - p.NewString(context, false, symbolName), - ) - return instantiatedError -} - -func (p *Plasma) NewObjectNotCallable(context *Context, objectType *Value) *Value { - errorType := p.ForceMasterGetAny(ObjectNotCallableError) - instantiatedError := p.ForceConstruction(context, errorType) - p.ForceInitialization(context, instantiatedError, objectType) - return instantiatedError -} - -func (p *Plasma) RuntimeErrorInitialize(context *Context, object *Value) *Value { - object.SetOnDemandSymbol(Initialize, - func() *Value { - return p.NewFunction(context, false, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - message := arguments[0] - if !message.IsTypeById(StringId) { - return p.NewInvalidTypeError(context, message.TypeName(), StringName), false - } - self.String = message.String - return p.GetNone(), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(ToString, - func() *Value { - return p.NewFunction(context, false, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.NewString(context, false, fmt.Sprintf("%s: %s", self.TypeName(), self.String)), true - }, - ), - ) - }, - ) - return nil -} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/vm/errors.go b/vendor/github.com/shoriwe/gplasma/pkg/vm/errors.go new file mode 100644 index 0000000..7f68dd6 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/vm/errors.go @@ -0,0 +1,9 @@ +package vm + +import "fmt" + +var ( + NotOperable = fmt.Errorf("not operable") + NotIndexable = fmt.Errorf("not indexable") + NotComparable = fmt.Errorf("not comparable") +) diff --git a/vendor/github.com/shoriwe/gplasma/pkg/vm/execute.go b/vendor/github.com/shoriwe/gplasma/pkg/vm/execute.go deleted file mode 100644 index 90a447e..0000000 --- a/vendor/github.com/shoriwe/gplasma/pkg/vm/execute.go +++ /dev/null @@ -1,196 +0,0 @@ -package vm - -func (p *Plasma) Execute(context *Context, bytecode *Bytecode) (*Value, bool) { - if context == nil { - context = p.NewContext() - } - var executionError *Value - for bytecode.HasNext() { - code := bytecode.Next() - - /* - if code.Line != 0 { - fmt.Println(color.GreenString(strconv.Itoa(code.Line)), instructionNames[code.Instruction.OpCode], code.Value) - } else { - fmt.Println(color.RedString("UL"), instructionNames[code.Instruction.OpCode], code.Value) - } - if context.ObjectStack.head != nil { - current := context.ObjectStack.head - for ; current != nil; current = current.next { - fmt.Println(current.value.(*Value).GetClass(p).Name, current.value.(*Value).Integer) - } - } - */ - - switch code.Instruction.OpCode { - case GetFalseOP: - context.LastObject = p.GetFalse() - case GetTrueOP: - context.LastObject = p.GetTrue() - case GetNoneOP: - context.LastObject = p.GetNone() - case NewStringOP: - executionError = p.newStringOP(context, code.Value.(string)) - case NewBytesOP: - executionError = p.newBytesOP(context, code.Value.([]uint8)) - case NewIntegerOP: - executionError = p.newIntegerOP(context, code.Value.(int64)) - case NewFloatOP: - executionError = p.newFloatOP(context, code.Value.(float64)) - case NewArrayOP: - executionError = p.newArrayOP(context, code.Value.(int)) - case NewTupleOP: - executionError = p.newTupleOP(context, code.Value.(int)) - case NewHashOP: - executionError = p.newHashTableOP(context, code.Value.(int)) - case UnaryOP: - executionError = p.unaryOP(context, code.Value.(uint8)) - case BinaryOP: - executionError = p.binaryOP(context, code.Value.(uint8)) - case MethodInvocationOP: - executionError = p.methodInvocationOP(context, code.Value.(int)) - case GetIdentifierOP: - executionError = p.getIdentifierOP(context, code.Value.(string)) - case SelectNameFromObjectOP: - executionError = p.selectNameFromObjectOP(context, code.Value.(string)) - case IndexOP: - executionError = p.indexOP(context) - case PushOP: - executionError = p.pushOP(context) - case AssignIdentifierOP: - executionError = p.assignIdentifierOP(context, code.Value.(string)) - case NewClassOP: - executionError = p.newClassOP(context, code.Value.(ClassInformation)) - case NewClassFunctionOP: - executionError = p.newClassFunctionOP(context, code.Value.(FunctionInformation)) - case NewFunctionOP: - executionError = p.newFunctionOP(context, code.Value.(FunctionInformation)) - case LoadFunctionArgumentsOP: - executionError = p.loadFunctionArgumentsOP(context, code.Value.([]string)) - case ReturnOP: - returnResult := p.returnOP(context, code.Value.(int)) - context.ReturnState() - return returnResult, true - case IfOneLinerOP: - executionError = p.ifOneLinerOP(context, code.Value.(ConditionInformation)) - case UnlessOneLinerOP: - executionError = p.unlessOneLinerOP(context, code.Value.(ConditionInformation)) - case AssignSelectorOP: - executionError = p.assignSelectorOP(context, code.Value.(string)) - case AssignIndexOP: - executionError = p.assignIndexOP(context) - case IfOP: - executionError = p.ifOP(context, code.Value.(ConditionInformation)) - if executionError != nil { - return executionError, false - } - switch context.LastState { - case BreakState, RedoState, ContinueState: - return p.GetNone(), true - case ReturnState: - result := context.LastObject - context.LastObject = nil - return result, true - } - case UnlessOP: - executionError = p.unlessOP(context, code.Value.(ConditionInformation)) - if executionError != nil { - return executionError, false - } - switch context.LastState { - case BreakState, RedoState, ContinueState: - return p.GetNone(), true - case ReturnState: - result := context.LastObject - context.LastObject = nil - return result, true - } - case ForLoopOP: - executionError = p.forLoopOP(context, code.Value.(LoopInformation)) - if executionError != nil { - return executionError, false - } else if context.LastState == ReturnState { - result := context.LastObject - context.LastObject = nil - return result, true - } - case NewGeneratorOP: - executionError = p.newGeneratorOP(context, code.Value.(int)) - case WhileLoopOP: - executionError = p.whileLoopOP(context, code.Value.(LoopInformation)) - if executionError != nil { - return executionError, false - } else if context.LastState == ReturnState { - result := context.LastObject - context.LastObject = nil - return result, true - } - case DoWhileLoopOP: - executionError = p.doWhileLoopOP(context, code.Value.(LoopInformation)) - if executionError != nil { - return executionError, false - } else if context.LastState == ReturnState { - result := context.LastObject - context.LastObject = nil - return result, true - } - case UntilLoopOP: - executionError = p.untilLoopOP(context, code.Value.(LoopInformation)) - if executionError != nil { - return executionError, false - } else if context.LastState == ReturnState { - result := context.LastObject - context.LastObject = nil - return result, true - } - case BreakOP: - context.BreakState() - return p.GetNone(), true - case ContinueOP: - context.ContinueState() - return p.GetNone(), true - case RedoOP: - context.RedoState() - return p.GetNone(), true - case NOP: - break - case TryOP: - executionError = p.tryOP(context, code.Value.(TryInformation)) - if executionError != nil { - return executionError, false - } - switch context.LastState { - case BreakState, RedoState, ContinueState: - return p.GetNone(), true - case ReturnState: - result := context.LastObject - context.LastObject = nil - return result, true - } - case RaiseOP: - executionError = context.PopObject() - case NewModuleOP: - executionError = p.newModuleOP(context, code.Value.(ClassInformation)) - case SwitchOP: - executionError = p.switchOP(context, code.Value.(SwitchInformation)) - if executionError != nil { - return executionError, false - } - switch context.LastState { - case BreakState, RedoState, ContinueState: - return p.GetNone(), true - case ReturnState: - result := context.LastObject - context.LastObject = nil - return result, true - } - default: - panic(instructionNames[code.Instruction.OpCode]) - } - if executionError != nil { - return executionError, false - } - } - context.NoState() - return p.GetNone(), true -} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/vm/float.go b/vendor/github.com/shoriwe/gplasma/pkg/vm/float.go index 7d2f256..41267f5 100644 --- a/vendor/github.com/shoriwe/gplasma/pkg/vm/float.go +++ b/vendor/github.com/shoriwe/gplasma/pkg/vm/float.go @@ -1,627 +1,330 @@ package vm import ( - "fmt" + "encoding/binary" + magic_functions "github.com/shoriwe/gplasma/pkg/common/magic-functions" "math" ) -func (p *Plasma) NewFloat(context *Context, isBuiltIn bool, value float64) *Value { - float_ := p.NewValue(context, isBuiltIn, FloatName, nil, context.PeekSymbolTable()) - float_.BuiltInTypeId = FloatId - float_.Float = value - p.FloatInitialize(isBuiltIn)(context, float_) - float_.SetOnDemandSymbol(Self, - func() *Value { - return float_ - }, - ) - return float_ +func (plasma *Plasma) floatClass() *Value { + class := plasma.NewValue(plasma.rootSymbols, BuiltInClassId, plasma.class) + class.SetAny(Callback(func(argument ...*Value) (*Value, error) { + return plasma.NewFloat(argument[0].Float()), nil + })) + return class } -func (p *Plasma) FloatInitialize(isBuiltIn bool) ConstructorCallBack { - return func(context *Context, object *Value) *Value { - object.SetOnDemandSymbol(Negative, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.NewFloat(context, false, - -self.Float, - ), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Add, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - right := arguments[0] - switch right.BuiltInTypeId { - case IntegerId: - return p.NewFloat(context, false, - self.Float+float64(right.Integer), - ), true - case FloatId: - return p.NewFloat(context, false, - self.Float+right.Float, - ), true - default: - return p.NewInvalidTypeError(context, right.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightAdd, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - left := arguments[0] - switch left.BuiltInTypeId { - case IntegerId: - return p.NewFloat(context, false, - float64(left.Integer)+self.Float, - ), true - case FloatId: - return p.NewFloat(context, false, - left.Float+self.Float, - ), true - default: - return p.NewInvalidTypeError(context, left.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Sub, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - right := arguments[0] - switch right.BuiltInTypeId { - case IntegerId: - return p.NewFloat(context, false, - self.Float-float64(right.Integer), - ), true - case FloatId: - return p.NewFloat(context, false, - self.Float-right.Float, - ), true - default: - return p.NewInvalidTypeError(context, right.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightSub, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - left := arguments[0] - switch left.BuiltInTypeId { - case IntegerId: - return p.NewFloat(context, false, - float64(left.Integer)-self.Float, - ), true - case FloatId: - return p.NewFloat(context, false, - left.Float-self.Float, - ), true - default: - return p.NewInvalidTypeError(context, left.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Mul, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - right := arguments[0] - switch right.BuiltInTypeId { - case IntegerId: - return p.NewFloat(context, false, - self.Float*float64(right.Integer), - ), true - case FloatId: - return p.NewFloat(context, false, - self.Float*right.Float, - ), true - default: - return p.NewInvalidTypeError(context, right.TypeName(), IntegerName, FloatName, StringName, ArrayName, TupleName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightMul, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - left := arguments[0] - switch left.BuiltInTypeId { - case IntegerId: - return p.NewFloat(context, false, - float64(left.Integer)*self.Float, - ), true - case FloatId: - return p.NewFloat(context, false, - left.Float*self.Float, - ), true - default: - return p.NewInvalidTypeError(context, left.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Div, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - right := arguments[0] - switch right.BuiltInTypeId { - case IntegerId: - return p.NewFloat(context, false, - self.Float/float64(right.Integer), - ), true - case FloatId: - return p.NewFloat(context, false, - self.Float/right.Float, - ), true - default: - return p.NewInvalidTypeError(context, right.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightDiv, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - left := arguments[0] - switch left.BuiltInTypeId { - case IntegerId: - return p.NewFloat(context, false, - float64(left.Integer)/self.Float, - ), true - case FloatId: - return p.NewFloat(context, false, - left.Float/self.Float, - ), true - default: - return p.NewInvalidTypeError(context, left.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Mod, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - right := arguments[0] - switch right.BuiltInTypeId { - case IntegerId: - return p.NewFloat(context, false, - math.Mod(self.Float, float64(right.Integer)), - ), true - case FloatId: - return p.NewFloat(context, false, - math.Mod(self.Float, right.Float), - ), true - default: - return p.NewInvalidTypeError(context, right.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightMod, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - left := arguments[0] - switch left.BuiltInTypeId { - case IntegerId: - return p.NewFloat(context, false, - math.Mod(float64(left.Integer), self.Float), - ), true - case FloatId: - return p.NewFloat(context, false, - math.Mod(left.Float, self.Float), - ), true - default: - return p.NewInvalidTypeError(context, left.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Pow, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - right := arguments[0] - switch right.BuiltInTypeId { - case IntegerId: - return p.NewFloat(context, false, - math.Pow( - self.Float, - float64(right.Integer), - ), - ), true - case FloatId: - return p.NewFloat(context, false, - math.Pow( - self.Float, - right.Float, - ), - ), true - default: - return p.NewInvalidTypeError(context, right.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightPow, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - left := arguments[0] - switch left.BuiltInTypeId { - case IntegerId: - return p.NewFloat(context, false, - math.Pow( - float64(left.Integer), - self.Float, - ), - ), true - case FloatId: - return p.NewFloat(context, false, - math.Pow( - float64(left.Integer), - self.Float, - ), - ), true - default: - return p.NewInvalidTypeError(context, left.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - - object.SetOnDemandSymbol(Equals, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - right := arguments[0] - switch right.BuiltInTypeId { - case IntegerId: - return p.InterpretAsBool(self.Float == float64(right.Integer)), true - case FloatId: - return p.InterpretAsBool(self.Float == right.Float), true - default: - return p.NewInvalidTypeError(context, right.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightEquals, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - left := arguments[0] - switch left.BuiltInTypeId { - case IntegerId: - return p.InterpretAsBool(float64(left.Integer) == self.Float), true - case FloatId: - return p.InterpretAsBool(left.Float == self.Float), true - default: - return p.NewInvalidTypeError(context, left.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(NotEquals, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - right := arguments[0] - switch right.BuiltInTypeId { - case IntegerId: - return p.InterpretAsBool(self.Float != float64(right.Integer)), true - case FloatId: - return p.InterpretAsBool(self.Float != right.Float), true - default: - return p.NewInvalidTypeError(context, right.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightNotEquals, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - left := arguments[0] - switch left.BuiltInTypeId { - case IntegerId: - return p.InterpretAsBool(float64(left.Integer) != self.Float), true - case FloatId: - return p.InterpretAsBool(left.Float != self.Float), true - default: - return p.NewInvalidTypeError(context, left.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(GreaterThan, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - right := arguments[0] - switch right.BuiltInTypeId { - case IntegerId: - return p.InterpretAsBool(self.Float > float64(right.Integer)), true - case FloatId: - return p.InterpretAsBool(self.Float > right.Float), true - default: - return p.NewInvalidTypeError(context, right.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightGreaterThan, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - left := arguments[0] - switch left.BuiltInTypeId { - case IntegerId: - return p.InterpretAsBool(float64(left.Integer) > self.Float), true - case FloatId: - return p.InterpretAsBool(left.Float > self.Float), true - default: - return p.NewInvalidTypeError(context, left.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(LessThan, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - right := arguments[0] - switch right.BuiltInTypeId { - case IntegerId: - return p.InterpretAsBool(self.Float < float64(right.Integer)), true - case FloatId: - return p.InterpretAsBool(self.Float < right.Float), true - default: - return p.NewInvalidTypeError(context, right.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightLessThan, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - left := arguments[0] - switch left.BuiltInTypeId { - case IntegerId: - return p.InterpretAsBool(float64(left.Integer) < self.Float), true - case FloatId: - return p.InterpretAsBool(left.Float < self.Float), true - default: - return p.NewInvalidTypeError(context, left.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(GreaterThanOrEqual, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - right := arguments[0] - switch right.BuiltInTypeId { - case IntegerId: - return p.InterpretAsBool(self.Float >= float64(right.Integer)), true - case FloatId: - return p.InterpretAsBool(self.Float >= right.Float), true - default: - return p.NewInvalidTypeError(context, right.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightGreaterThanOrEqual, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - left := arguments[0] - switch left.BuiltInTypeId { - case IntegerId: - return p.InterpretAsBool(float64(left.Integer) >= self.Float), true - case FloatId: - return p.InterpretAsBool(left.Float >= self.Float), true - default: - return p.NewInvalidTypeError(context, left.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(LessThanOrEqual, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - right := arguments[0] - switch right.BuiltInTypeId { - case IntegerId: - return p.InterpretAsBool(self.Float <= float64(right.Integer)), true - case FloatId: - return p.InterpretAsBool(self.Float <= right.Float), true - default: - return p.NewInvalidTypeError(context, right.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightLessThanOrEqual, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - left := arguments[0] - switch left.BuiltInTypeId { - case IntegerId: - return p.InterpretAsBool(float64(left.Integer) <= self.Float), true - case FloatId: - return p.InterpretAsBool(left.Float <= self.Float), true - default: - return p.NewInvalidTypeError(context, left.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - - object.SetOnDemandSymbol(Hash, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - if self.GetHash() == 0 { - floatHash := p.HashString(fmt.Sprintf("%f-%s", self.Float, FloatName)) - self.SetHash(floatHash) - } - return p.NewInteger(context, false, self.GetHash()), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Copy, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.NewFloat(context, false, self.Float), true - }, +/* +NewFloat magic function: +Positive: __positive__ +Negative: __negative__ +NegateBits: __negate_bits__ +Equal: __equal__ +NotEqual: __not_equal__ +GreaterThan: __greater_than__ +GreaterOrEqualThan: __greater_or_equal_than__ +LessThan: __less_than__ +LessOrEqualThan: __less_or_equal_than__ +BitwiseOr: __bitwise_or__ +BitwiseXor: __bitwise_xor__ +BitwiseAnd: __bitwise_and__ +BitwiseLeft: __bitwise_left__ +BitwiseRight: __bitwise_right__ +Add: __add__ +Sub: __sub__ +Mul: __mul__ +Div: __div__ +FloorDiv: __floor_div__ +Modulus: __mod__ +PowerOf: __pow__ +Bool: __bool__ +String __string__ +Int __int__ +Float __float__ +Copy: __copy__ +BigEndian big_endian +LittleEndian little_endian +FromBig from_big +FromLittle from_little +*/ +func (plasma *Plasma) NewFloat(f float64) *Value { + result := plasma.NewValue(plasma.rootSymbols, FloatId, plasma.float) + result.SetAny(f) + result.Set(magic_functions.Positive, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return result, nil + }, + )) + result.Set(magic_functions.Negative, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewFloat(-result.Float()), nil + }, + )) + result.Set(magic_functions.NegateBits, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewFloat(math.Float64frombits(^math.Float64bits(result.Float()))), nil + }, + )) + result.Set(magic_functions.Equal, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case IntId, FloatId: + return plasma.NewBool(result.Equal(argument[0])), nil + } + return plasma.false, nil + }, + )) + result.Set(magic_functions.NotEqual, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case IntId, FloatId: + return plasma.NewBool(!result.Equal(argument[0])), nil + } + return plasma.true, nil + }, + )) + result.Set(magic_functions.GreaterThan, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case IntId, FloatId: + return plasma.NewBool(result.Float() > argument[0].Float()), nil + } + return nil, NotComparable + }, + )) + result.Set(magic_functions.GreaterOrEqualThan, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case IntId, FloatId: + return plasma.NewBool(result.Float() >= argument[0].Float()), nil + } + return nil, NotComparable + }, + )) + result.Set(magic_functions.LessThan, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case IntId, FloatId: + return plasma.NewBool(result.Float() < argument[0].Float()), nil + } + return nil, NotComparable + }, + )) + result.Set(magic_functions.LessOrEqualThan, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case IntId, FloatId: + return plasma.NewBool(result.Float() <= argument[0].Float()), nil + } + return nil, NotComparable + }, + )) + result.Set(magic_functions.BitwiseOr, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case IntId, FloatId: + return plasma.NewFloat( + math.Float64frombits( + math.Float64bits(result.Float()) | math.Float64bits(argument[0].Float()), ), - ) - }, - ) - - object.SetOnDemandSymbol(ToInteger, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.NewInteger(context, false, int64(self.Float)), true - }, + ), nil + } + return nil, NotOperable + }, + )) + result.Set(magic_functions.BitwiseXor, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case IntId, FloatId: + return plasma.NewFloat( + math.Float64frombits( + math.Float64bits(result.Float()) ^ math.Float64bits(argument[0].Float()), ), - ) - }, - ) - object.SetOnDemandSymbol(ToFloat, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.NewFloat(context, false, self.Float), true - }, + ), nil + } + return nil, NotOperable + }, + )) + result.Set(magic_functions.BitwiseAnd, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case IntId, FloatId: + return plasma.NewFloat( + math.Float64frombits( + math.Float64bits(result.Float()) & math.Float64bits(argument[0].Float()), ), - ) - }, - ) - object.SetOnDemandSymbol(ToString, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.NewString(context, false, fmt.Sprint(self.Float)), true - }, + ), nil + } + return nil, NotOperable + }, + )) + result.Set(magic_functions.BitwiseLeft, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case IntId, FloatId: + return plasma.NewFloat( + math.Float64frombits( + math.Float64bits(result.Float()) << math.Float64bits(argument[0].Float()), ), - ) - }, - ) - object.SetOnDemandSymbol(ToBool, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.InterpretAsBool(self.Float != 0), true - }, + ), nil + } + return nil, NotOperable + }, + )) + result.Set(magic_functions.BitwiseRight, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case IntId, FloatId: + return plasma.NewFloat( + math.Float64frombits( + math.Float64bits(result.Float()) >> math.Float64bits(argument[0].Float()), ), - ) - }, - ) - return nil - } + ), nil + } + return nil, NotOperable + }, + )) + result.Set(magic_functions.Add, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case IntId, FloatId: + return plasma.NewFloat(result.Float() + argument[0].Float()), nil + } + return nil, NotOperable + }, + )) + result.Set(magic_functions.Sub, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case IntId, FloatId: + return plasma.NewFloat(result.Float() - argument[0].Float()), nil + } + return nil, NotOperable + }, + )) + result.Set(magic_functions.Mul, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case IntId, FloatId: + return plasma.NewFloat(result.Float() * argument[0].Float()), nil + } + return nil, NotOperable + }, + )) + result.Set(magic_functions.Div, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case IntId, FloatId: + return plasma.NewFloat(result.Float() / argument[0].Float()), nil + } + return nil, NotOperable + }, + )) + result.Set(magic_functions.FloorDiv, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case IntId, FloatId: + return plasma.NewInt(int64(result.Float() / argument[0].Float())), nil + } + return nil, NotOperable + }, + )) + result.Set(magic_functions.Modulus, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case IntId, FloatId: + return plasma.NewFloat(math.Mod(result.Float(), argument[0].Float())), nil + } + return nil, NotOperable + }, + )) + result.Set(magic_functions.PowerOf, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case IntId, FloatId: + return plasma.NewFloat(math.Pow(result.Float(), argument[0].Float())), nil + } + return nil, NotOperable + }, + )) + result.Set(magic_functions.Bool, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewBool(result.Bool()), nil + }, + )) + result.Set(magic_functions.String, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewString([]byte(result.String())), nil + }, + )) + result.Set(magic_functions.Int, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewInt(result.Int()), nil + }, + )) + result.Set(magic_functions.Float, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return result, nil + }, + )) + result.Set(magic_functions.Copy, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewFloat(result.Float()), nil + }, + )) + result.Set(magic_functions.BigEndian, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + b := make([]byte, 8) + binary.BigEndian.PutUint64(b, math.Float64bits(result.Float())) + return plasma.NewBytes(b), nil + }, + )) + result.Set(magic_functions.LittleEndian, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + b := make([]byte, 8) + binary.LittleEndian.PutUint64(b, math.Float64bits(result.Float())) + return plasma.NewBytes(b), nil + }, + )) + result.Set(magic_functions.FromBig, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewFloat(math.Float64frombits(binary.BigEndian.Uint64(argument[0].GetBytes()))), nil + }, + )) + result.Set(magic_functions.FromLittle, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewFloat(math.Float64frombits(binary.LittleEndian.Uint64(argument[0].GetBytes()))), nil + }, + )) + return result } diff --git a/vendor/github.com/shoriwe/gplasma/pkg/vm/function.go b/vendor/github.com/shoriwe/gplasma/pkg/vm/function.go index 828a0e2..29d3dfa 100644 --- a/vendor/github.com/shoriwe/gplasma/pkg/vm/function.go +++ b/vendor/github.com/shoriwe/gplasma/pkg/vm/function.go @@ -1,13 +1,19 @@ package vm -func (p *Plasma) NewFunction(context *Context, isBuiltIn bool, parentSymbols *SymbolTable, callable Callable) *Value { - function := p.NewValue(context, isBuiltIn, FunctionName, nil, parentSymbols) - function.BuiltInTypeId = FunctionId - function.Callable = callable - function.SetOnDemandSymbol(Self, - func() *Value { - return function - }, - ) +func (plasma *Plasma) functionClass() *Value { + class := plasma.NewValue(plasma.rootSymbols, BuiltInClassId, plasma.class) + class.SetAny(Callback(func(argument ...*Value) (*Value, error) { + return plasma.NewBuiltInFunction( + plasma.rootSymbols, + func(argument ...*Value) (*Value, error) { + return plasma.none, nil + }), nil + })) + return class +} + +func (plasma *Plasma) NewBuiltInFunction(parent *Symbols, callback Callback) *Value { + function := plasma.NewValue(parent, BuiltInFunctionId, plasma.function) + function.SetAny(callback) return function } diff --git a/vendor/github.com/shoriwe/gplasma/pkg/vm/function_names.go b/vendor/github.com/shoriwe/gplasma/pkg/vm/function_names.go deleted file mode 100644 index 81ead46..0000000 --- a/vendor/github.com/shoriwe/gplasma/pkg/vm/function_names.go +++ /dev/null @@ -1,92 +0,0 @@ -package vm - -const ( - Self = "self" - Initialize = "Initialize" - NegateBits = "NegateBits" - Negate = "Negate" - Negative = "Negative" - Add = "Add" - RightAdd = "RightAdd" - Sub = "Sub" - RightSub = "RightSub" - Mul = "Mul" - RightMul = "RightMul" - Div = "Div" - RightDiv = "RightDiv" - FloorDiv = "FloorDiv" - RightFloorDiv = "RightFloorDiv" - Mod = "Mod" - RightMod = "RightMod" - Pow = "Pow" - RightPow = "RightPow" - BitXor = "BitXor" - RightBitXor = "RightBitXor" - BitAnd = "BitAnd" - RightBitAnd = "RightBitAnd" - BitOr = "BitOr" - RightBitOr = "RightBitOr" - BitLeft = "BitLeft" - RightBitLeft = "RightBitLeft" - BitRight = "BitRight" - RightBitRight = "RightBitRight" - And = "And" - RightAnd = "RightAnd" - Or = "Or" - RightOr = "RightOr" - Xor = "Xor" - RightXor = "RightXor" - Equals = "Equals" - RightEquals = "RightEquals" - NotEquals = "NotEquals" - RightNotEquals = "RightNotEquals" - GreaterThan = "GreaterThan" - RightGreaterThan = "RightGreaterThan" - LessThan = "LessThan" - RightLessThan = "RightLessThan" - GreaterThanOrEqual = "GreaterThanOrEqual" - RightGreaterThanOrEqual = "RightGreaterThanOrEqual" - LessThanOrEqual = "LessThanOrEqual" - RightLessThanOrEqual = "RightLessThanOrEqual" - Contains = "Contains" - Hash = "Hash" - Copy = "Copy" - Index = "Index" - Assign = "Assign" - Call = "Call" - Iter = "Iter" - HasNext = "HasNext" - Next = "Next" - Class = "Class" - SubClasses = "SubClasses" - ToInteger = "ToInteger" - ToFloat = "ToFloat" - ToString = "ToString" - ToBool = "ToBool" - ToArray = "ToArray" - ToTuple = "ToTuple" - ToBytes = "ToBytes" - GetInteger = "GetInteger" - GetBool = "GetBool" - GetBytes = "GetBytes" - GetString = "GetString" - GetFloat = "GetFloat" - GetContent = "GetContent" - GetKeyValues = "GetKeyValues" - SetBool = "SetBool" - SetBytes = "SetBytes" - SetString = "SetString" - SetInteger = "SetInteger" - SetFloat = "SetFloat" - SetContent = "SetContent" - SetKeyValues = "SetKeyValues" - Append = "Append" - Delete = "Delete" - Lower = "Lower" - Upper = "Upper" - Split = "Split" - Replace = "Replace" - IsMain = "IsMain" - Length = "Length" - Pop = "Pop" -) diff --git a/vendor/github.com/shoriwe/gplasma/pkg/vm/hash-internal.go b/vendor/github.com/shoriwe/gplasma/pkg/vm/hash-internal.go new file mode 100644 index 0000000..03e41f4 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/vm/hash-internal.go @@ -0,0 +1,125 @@ +package vm + +import ( + "fmt" + "reflect" + "sync" +) + +var ( + NotHashable = fmt.Errorf("not hashable") +) + +func createHashString(a any) string { + return fmt.Sprintf("%s -- %v", reflect.TypeOf(a), a) +} + +type Hash struct { + mutex *sync.Mutex + internalMap map[string]*Value +} + +func (h *Hash) Size() int64 { + h.mutex.Lock() + defer h.mutex.Unlock() + return int64(len(h.internalMap)) +} + +func (h *Hash) Set(key, value *Value) error { + h.mutex.Lock() + defer h.mutex.Unlock() + switch key.TypeId() { + case StringId: + h.internalMap[createHashString(string(key.GetBytes()))] = value + case BytesId: + h.internalMap[createHashString(key.GetBytes())] = value + case BoolId: + h.internalMap[createHashString(key.GetBool())] = value + case IntId: + h.internalMap[createHashString(key.GetInt64())] = value + case FloatId: + h.internalMap[createHashString(key.GetFloat64())] = value + default: + return NotHashable + } + return nil +} + +func (h *Hash) Get(key *Value) (*Value, error) { + h.mutex.Lock() + defer h.mutex.Unlock() + switch key.TypeId() { + case StringId: + return h.internalMap[createHashString(string(key.GetBytes()))], nil + case BytesId: + return h.internalMap[createHashString(key.GetBytes())], nil + case BoolId: + return h.internalMap[createHashString(key.GetBool())], nil + case IntId: + return h.internalMap[createHashString(key.GetInt64())], nil + case FloatId: + return h.internalMap[createHashString(key.GetFloat64())], nil + } + return nil, NotHashable +} + +func (h *Hash) Del(key *Value) error { + h.mutex.Lock() + defer h.mutex.Unlock() + switch key.TypeId() { + case StringId: + delete(h.internalMap, createHashString(string(key.GetBytes()))) + case BytesId: + delete(h.internalMap, createHashString(key.GetBytes())) + case BoolId: + delete(h.internalMap, createHashString(key.GetBool())) + case IntId: + delete(h.internalMap, createHashString(key.GetInt64())) + case FloatId: + delete(h.internalMap, createHashString(key.GetFloat64())) + default: + return NotHashable + } + return nil +} + +func (h *Hash) Copy() *Hash { + h.mutex.Lock() + defer h.mutex.Unlock() + result := &Hash{ + mutex: &sync.Mutex{}, + internalMap: make(map[string]*Value, len(h.internalMap)), + } + for key, value := range h.internalMap { + result.internalMap[key] = value + } + return result +} + +func (h *Hash) In(key *Value) (bool, error) { + h.mutex.Lock() + defer h.mutex.Unlock() + var found bool + switch key.TypeId() { + case StringId: + _, found = h.internalMap[createHashString(string(key.GetBytes()))] + case BytesId: + _, found = h.internalMap[createHashString(key.GetBytes())] + case BoolId: + _, found = h.internalMap[createHashString(key.GetBool())] + case IntId: + _, found = h.internalMap[createHashString(key.GetInt64())] + case FloatId: + _, found = h.internalMap[createHashString(key.GetFloat64())] + default: + return false, NotHashable + } + return found, nil +} + +func (plasma *Plasma) NewInternalHash() *Hash { + return &Hash{ + mutex: &sync.Mutex{}, + internalMap: map[string]*Value{}, + } +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/vm/hash.go b/vendor/github.com/shoriwe/gplasma/pkg/vm/hash.go new file mode 100644 index 0000000..2ca39a3 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/vm/hash.go @@ -0,0 +1,84 @@ +package vm + +import magic_functions "github.com/shoriwe/gplasma/pkg/common/magic-functions" + +func (plasma *Plasma) hashClass() *Value { + class := plasma.NewValue(plasma.rootSymbols, BuiltInClassId, plasma.class) + class.SetAny(Callback(func(argument ...*Value) (*Value, error) { + return plasma.NewHash(argument[0].GetHash()), nil + })) + return class +} + +/* +NewHash magic function: +In __in__ +Length __len__ +Bool __bool__ +String __string__ +Bytes __bytes__ +Get __get__ +Set __set__ +Del __del__ +Copy __copy__ +*/ +func (plasma *Plasma) NewHash(hash *Hash) *Value { + result := plasma.NewValue(plasma.rootSymbols, HashId, plasma.hash) + result.SetAny(hash) + result.Set(magic_functions.In, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + in, inError := result.GetHash().In(argument[0]) + return plasma.NewBool(in), inError + }, + )) + result.Set(magic_functions.Length, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewInt(result.GetHash().Size()), nil + }, + )) + result.Set(magic_functions.Bool, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewBool(result.Bool()), nil + }, + )) + result.Set(magic_functions.String, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewString([]byte(result.String())), nil + }, + )) + result.Set(magic_functions.Bytes, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewBytes([]byte(result.String())), nil + }, + )) + result.Set(magic_functions.Get, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return result.GetHash().Get(argument[0]) + }, + )) + result.Set(magic_functions.Set, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.none, result.GetHash().Set(argument[0], argument[1]) + }, + )) + result.Set(magic_functions.Del, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.none, result.GetHash().Del(argument[0]) + }, + )) + result.Set(magic_functions.Copy, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewHash(result.GetHash().Copy()), nil + }, + )) + return result +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/vm/hashing.go b/vendor/github.com/shoriwe/gplasma/pkg/vm/hashing.go deleted file mode 100644 index c293632..0000000 --- a/vendor/github.com/shoriwe/gplasma/pkg/vm/hashing.go +++ /dev/null @@ -1,7 +0,0 @@ -package vm - -const ( - XXPrime1 uint64 = 11400714785074694791 - XXPrime2 uint64 = 14029467366897019727 - XXPrime5 uint64 = 2870177450012600261 -) diff --git a/vendor/github.com/shoriwe/gplasma/pkg/vm/hashtable.go b/vendor/github.com/shoriwe/gplasma/pkg/vm/hashtable.go deleted file mode 100644 index 5043dd3..0000000 --- a/vendor/github.com/shoriwe/gplasma/pkg/vm/hashtable.go +++ /dev/null @@ -1,248 +0,0 @@ -package vm - -type KeyValue struct { - Key *Value - Value *Value -} - -func (p *Plasma) NewHashTable(context *Context, isBuiltIn bool) *Value { - hashTable := p.NewValue(context, isBuiltIn, HashName, nil, context.PeekSymbolTable()) - hashTable.BuiltInTypeId = HashTableId - p.HashTableInitialize(isBuiltIn)(context, hashTable) - hashTable.SetOnDemandSymbol(Self, - func() *Value { - return hashTable - }, - ) - return hashTable -} - -func (p *Plasma) HashTableInitialize(isBuiltIn bool) ConstructorCallBack { - return func(context *Context, object *Value) *Value { - object.SetOnDemandSymbol(Length, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, arguments ...*Value) (*Value, bool) { - return p.NewInteger(context, false, int64(len(self.KeyValues))), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Equals, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - return p.HashEquals(context, self, arguments[0]) - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightEquals, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - return p.HashEquals(context, arguments[0], self) - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(NotEquals, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - return p.HashNotEquals(context, self, arguments[0]) - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightNotEquals, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - return p.HashNotEquals(context, arguments[0], self) - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Contains, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - return p.HashContains(context, self, arguments[0]) - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Hash, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(_ *Value, _ ...*Value) (*Value, bool) { - return p.NewUnhashableTypeError(context, p.ForceMasterGetAny(HashName)), false - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Copy, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(_ *Value, _ ...*Value) (*Value, bool) { - return p.NewUnhashableTypeError(context, object.GetClass(p)), false - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Index, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - return p.HashIndex(context, self, arguments[0]) - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Assign, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 2, - func(self *Value, arguments ...*Value) (*Value, bool) { - return p.HashIndexAssign(context, self, arguments[0], arguments[1]) - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Iter, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.HashIterator(context, self) - }, - ), - ) - }, - ) - - object.SetOnDemandSymbol(ToString, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - result := "{" - var ( - valueToString *Value - valueString *Value - ) - for _, keyValues := range self.KeyValues { - for _, keyValue := range keyValues { - keyToString, getError := keyValue.Key.Get(p, context, ToString) - if getError != nil { - return getError, false - } - keyString, success := p.CallFunction(context, keyToString) - if !success { - return keyString, false - } - result += keyString.String - valueToString, getError = keyValue.Value.Get(p, context, ToString) - if getError != nil { - return getError, false - } - valueString, success = p.CallFunction(context, valueToString) - if !success { - return valueString, false - } - result += ": " + valueString.String + ", " - } - } - if len(result) > 1 { - result = result[:len(result)-2] - } - return p.NewString(context, false, result+"}"), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(ToBool, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.InterpretAsBool(len(self.KeyValues) > 0), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(ToArray, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.HashToContent(context, self, ArrayId) - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(ToTuple, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.HashToContent(context, self, TupleId) - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Delete, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - keyHash, success := p.Hash(context, arguments[0]) - if !success { - return keyHash, false - } - if _, found := self.KeyValues[keyHash.Integer]; !found { - return p.NewKeyNotFoundError(context, arguments[0]), false - } - for index, keyValue := range self.KeyValues[keyHash.Integer] { - doesEquals, equalsError := p.Equals(context, keyValue.Key, arguments[0]) - if equalsError != nil { - return equalsError, false - } - if doesEquals { - self.KeyValues[keyHash.Integer] = append(self.KeyValues[keyHash.Integer][:index], self.KeyValues[keyHash.Integer][index+1:]...) - return p.GetNone(), true - } - } - return p.NewKeyNotFoundError(context, arguments[0]), false - }, - ), - ) - }, - ) - return nil - } -} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/vm/init.go b/vendor/github.com/shoriwe/gplasma/pkg/vm/init.go new file mode 100644 index 0000000..f797982 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/vm/init.go @@ -0,0 +1,248 @@ +package vm + +import ( + "bufio" + magic_functions "github.com/shoriwe/gplasma/pkg/common/magic-functions" + special_symbols "github.com/shoriwe/gplasma/pkg/common/special-symbols" +) + +func (plasma *Plasma) init() { + // On Demand values + plasma.onDemand = map[string]func(*Value) *Value{ + magic_functions.Equal: func(self *Value) *Value { + return plasma.NewBuiltInFunction( + self.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewBool(self == argument[0]), nil + }, + ) + }, + magic_functions.NotEqual: func(self *Value) *Value { + return plasma.NewBuiltInFunction( + self.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewBool(self != argument[0]), nil + }, + ) + }, + magic_functions.And: func(self *Value) *Value { + return plasma.NewBuiltInFunction(self.vtable, + func(argument ...*Value) (*Value, error) { + if self.Bool() && argument[0].Bool() { + return plasma.true, nil + } + return plasma.false, nil + }) + }, + magic_functions.Or: func(self *Value) *Value { + return plasma.NewBuiltInFunction(self.vtable, + func(argument ...*Value) (*Value, error) { + if self.Bool() || argument[0].Bool() { + return plasma.true, nil + } + return plasma.false, nil + }) + }, + magic_functions.Xor: func(self *Value) *Value { + return plasma.NewBuiltInFunction(self.vtable, + func(argument ...*Value) (*Value, error) { + if self.Bool() != argument[0].Bool() { + return plasma.true, nil + } + return plasma.false, nil + }) + }, + magic_functions.Is: func(self *Value) *Value { + return plasma.NewBuiltInFunction(self.vtable, + func(argument ...*Value) (*Value, error) { + class := argument[0] + switch class.TypeId() { + case BuiltInClassId, ClassId: + return plasma.NewBool(self.GetClass() == class), nil + } + return plasma.false, nil + }) + }, + magic_functions.Implements: func(self *Value) *Value { + return plasma.NewBuiltInFunction(self.vtable, + func(argument ...*Value) (*Value, error) { + class := argument[0] + switch class.TypeId() { + case BuiltInClassId, ClassId: + return plasma.NewBool(self.GetClass().Implements(class)), nil + } + return plasma.false, nil + }) + }, + magic_functions.Bool: func(self *Value) *Value { + return plasma.NewBuiltInFunction(self.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewBool(self.Bool()), nil + }) + }, + magic_functions.Class: func(self *Value) *Value { + return plasma.NewBuiltInFunction(self.vtable, + func(argument ...*Value) (*Value, error) { + return self.GetClass(), nil + }) + }, + magic_functions.SubClasses: func(self *Value) *Value { + return plasma.NewBuiltInFunction(self.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewTuple(self.GetClass().GetClassInfo().Bases), nil + }) + }, + magic_functions.Iter: func(self *Value) *Value { + return plasma.NewBuiltInFunction( + self.vtable, + func(argument ...*Value) (*Value, error) { + return self, nil + }, + ) + }, + } + // Init classes + plasma.metaClass() + plasma.value = plasma.valueClass() + plasma.function = plasma.functionClass() + plasma.string = plasma.stringClass() + plasma.bytes = plasma.bytesClass() + plasma.bool = plasma.boolClass() + plasma.noneType = plasma.noneClass() + plasma.int = plasma.integerClass() + plasma.float = plasma.floatClass() + plasma.array = plasma.arrayClass() + plasma.tuple = plasma.tupleClass() + plasma.hash = plasma.hashClass() + // Init values + plasma.true = plasma.NewBool(true) + plasma.false = plasma.NewBool(false) + plasma.none = plasma.NewNone() + // Init symbols + // -- Classes + plasma.rootSymbols.Set(special_symbols.Value, plasma.value) + plasma.rootSymbols.Set(special_symbols.String, plasma.string) + plasma.rootSymbols.Set(special_symbols.Bytes, plasma.bytes) + plasma.rootSymbols.Set(special_symbols.Bool, plasma.bool) + plasma.rootSymbols.Set(special_symbols.None, plasma.noneType) + plasma.rootSymbols.Set(special_symbols.Int, plasma.int) + plasma.rootSymbols.Set(special_symbols.Float, plasma.float) + plasma.rootSymbols.Set(special_symbols.Array, plasma.array) + plasma.rootSymbols.Set(special_symbols.Tuple, plasma.tuple) + plasma.rootSymbols.Set(special_symbols.Hash, plasma.hash) + plasma.rootSymbols.Set(special_symbols.Function, plasma.function) + plasma.rootSymbols.Set(special_symbols.Class, plasma.class) + /* + - input + - print + - println + - range + */ + plasma.rootSymbols.Set(special_symbols.Input, plasma.NewBuiltInFunction(plasma.rootSymbols, + func(argument ...*Value) (*Value, error) { + _, writeError := plasma.Stdout.Write([]byte(argument[0].String())) + if writeError != nil { + panic(writeError) + } + scanner := bufio.NewScanner(plasma.Stdin) + if scanner.Scan() { + return plasma.NewString(scanner.Bytes()), nil + } + return plasma.none, nil + }, + )) + plasma.rootSymbols.Set(special_symbols.Print, plasma.NewBuiltInFunction(plasma.rootSymbols, + func(argument ...*Value) (*Value, error) { + for index, arg := range argument { + if index != 0 { + _, writeError := plasma.Stdout.Write([]byte(" ")) + if writeError != nil { + panic(writeError) + } + } + _, writeError := plasma.Stdout.Write([]byte(arg.String())) + if writeError != nil { + panic(writeError) + } + + } + return plasma.none, nil + }, + )) + plasma.rootSymbols.Set(special_symbols.Println, plasma.NewBuiltInFunction(plasma.rootSymbols, + func(argument ...*Value) (*Value, error) { + for index, arg := range argument { + if index != 0 { + _, writeError := plasma.Stdout.Write([]byte(" ")) + if writeError != nil { + panic(writeError) + } + } + _, writeError := plasma.Stdout.Write([]byte(arg.String())) + if writeError != nil { + panic(writeError) + } + } + _, writeError := plasma.Stdout.Write([]byte("\n")) + if writeError != nil { + panic(writeError) + } + return plasma.none, nil + }, + )) + plasma.rootSymbols.Set(special_symbols.Range, plasma.NewBuiltInFunction(plasma.rootSymbols, + func(argument ...*Value) (*Value, error) { + var ( + start = argument[0] + end = argument[1] + intStep int64 = 1 + floatStep = 1.0 + useFloatStep = start.TypeId() == FloatId || end.TypeId() == FloatId + ) + if len(argument) == 3 { + step := argument[2] + intStep = step.Int() + floatStep = step.Float() + if !useFloatStep { + useFloatStep = step.TypeId() == FloatId + } + } + iter := plasma.NewValue(plasma.rootSymbols, ValueId, plasma.value) + if useFloatStep { + iter.SetAny(start.Float()) + iter.Set(magic_functions.HasNext, plasma.NewBuiltInFunction( + iter.vtable, + func(_ ...*Value) (*Value, error) { + return plasma.NewBool(iter.GetFloat64() < end.Float()), nil + }, + )) + iter.Set(magic_functions.Next, plasma.NewBuiltInFunction( + iter.vtable, + func(_ ...*Value) (*Value, error) { + current := iter.GetFloat64() + // fmt.Println(current) + iter.SetAny(current + floatStep) + return plasma.NewFloat(current), nil + }, + )) + } else { + iter.SetAny(start.Int()) + iter.Set(magic_functions.HasNext, plasma.NewBuiltInFunction( + iter.vtable, + func(_ ...*Value) (*Value, error) { + return plasma.NewBool(iter.GetInt64() < end.Int()), nil + }, + )) + iter.Set(magic_functions.Next, plasma.NewBuiltInFunction( + iter.vtable, + func(_ ...*Value) (*Value, error) { + current := iter.GetInt64() + iter.SetAny(current + intStep) + return plasma.NewInt(current), nil + }, + )) + } + return iter, nil + }, + )) +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/vm/instruction_information.go b/vendor/github.com/shoriwe/gplasma/pkg/vm/instruction_information.go deleted file mode 100644 index c2b139d..0000000 --- a/vendor/github.com/shoriwe/gplasma/pkg/vm/instruction_information.go +++ /dev/null @@ -1,45 +0,0 @@ -package vm - -type ClassInformation struct { - Name string - Body []*Code -} - -type FunctionInformation struct { - Name string - Body []*Code - NumberOfArguments int -} - -type ConditionInformation struct { - Body []*Code - ElseBody []*Code -} - -type LoopInformation struct { - Body []*Code - Condition []*Code - Receivers []string -} - -type ExceptInformation struct { - CaptureName string - Targets []*Code - Body []*Code -} - -type TryInformation struct { - Body []*Code - Excepts []ExceptInformation - Finally []*Code -} - -type CaseInformation struct { - Targets []*Code - Body []*Code -} - -type SwitchInformation struct { - Cases []CaseInformation - Default []*Code -} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/vm/instructions.go b/vendor/github.com/shoriwe/gplasma/pkg/vm/instructions.go deleted file mode 100644 index 4d85e67..0000000 --- a/vendor/github.com/shoriwe/gplasma/pkg/vm/instructions.go +++ /dev/null @@ -1,722 +0,0 @@ -package vm - -func (p *Plasma) newStringOP(context *Context, s string) *Value { - context.LastObject = p.NewString(context, false, s) - return nil -} - -func (p *Plasma) newBytesOP(context *Context, bytes []uint8) *Value { - context.LastObject = p.NewBytes(context, false, bytes) - return nil -} - -func (p *Plasma) newIntegerOP(context *Context, i int64) *Value { - context.LastObject = p.NewInteger(context, false, i) - return nil -} - -func (p *Plasma) newFloatOP(context *Context, f float64) *Value { - context.LastObject = p.NewFloat(context, false, f) - return nil -} - -func (p *Plasma) newArrayOP(context *Context, length int) *Value { - content := make([]*Value, length) - for index := 0; index < length; index++ { - content[index] = context.PopObject() - } - context.LastObject = p.NewArray(context, false, content) - return nil -} - -func (p *Plasma) newTupleOP(context *Context, length int) *Value { - content := make([]*Value, length) - for index := 0; index < length; index++ { - content[index] = context.PopObject() - } - context.LastObject = p.NewTuple(context, false, content) - return nil -} - -func (p *Plasma) newHashTableOP(context *Context, length int) *Value { - result := p.NewHashTable(context, false) - for index := 0; index < length; index++ { - key := context.PopObject() - value := context.PopObject() - assignResult, success := p.HashIndexAssign(context, result, key, value) - if !success { - return assignResult - } - } - context.LastObject = result - return nil -} - -func (p *Plasma) unaryOP(context *Context, unaryOperation uint8) *Value { - unaryName := unaryInstructionsFunctions[unaryOperation] - target := context.PopObject() - operation, getError := target.Get(p, context, unaryName) - if getError != nil { - return getError - } - result, success := p.CallFunction(context, operation) - if !success { - return result - } - context.LastObject = result - return nil -} - -func (p *Plasma) binaryOPRightHandSide(context *Context, leftHandSide *Value, rightHandSide *Value, rightOperationName string) *Value { - rightHandSideOperation, getError := rightHandSide.Get(p, context, rightOperationName) - if getError != nil { - return getError - } - result, success := p.CallFunction(context, rightHandSideOperation, leftHandSide) - if !success { - return result - } - context.LastObject = result - return nil -} - -func (p *Plasma) binaryOP(context *Context, binaryOperation uint8) *Value { - binaryNames := binaryInstructionsFunctions[binaryOperation] - leftHandSide := context.PopObject() - rightHandSide := context.PopObject() - leftHandSideOperation, getError := leftHandSide.Get(p, context, binaryNames[0]) - if getError != nil { - return p.binaryOPRightHandSide(context, leftHandSide, rightHandSide, binaryNames[1]) - } - result, success := p.CallFunction(context, leftHandSideOperation, rightHandSide) - if !success { - return p.binaryOPRightHandSide(context, leftHandSide, rightHandSide, binaryNames[1]) - } - context.LastObject = result - return nil -} - -func (p *Plasma) methodInvocationOP(context *Context, numberOfArguments int) *Value { - method := context.PopObject() - var arguments []*Value - for index := 0; index < numberOfArguments; index++ { - arguments = append(arguments, context.PopObject()) - } - result, success := p.CallFunction(context, method, arguments...) - if !success { - return result - } - context.LastObject = result - return nil -} - -func (p *Plasma) getIdentifierOP(context *Context, symbol string) *Value { - result, getError := context.PeekSymbolTable().GetAny(symbol) - if getError != nil { - return p.NewObjectWithNameNotFoundError(context, p.ForceMasterGetAny(ValueName), symbol) - } - context.LastObject = result - return nil -} - -func (p *Plasma) selectNameFromObjectOP(context *Context, symbol string) *Value { - source := context.PopObject() - result, getError := source.Get(p, context, symbol) - if getError != nil { - return getError - } - context.LastObject = result - return nil -} - -func (p *Plasma) indexOP(context *Context) *Value { - index := context.PopObject() - source := context.PopObject() - result, success := p.IndexCall(context, source, index) - if !success { - return result - } - context.LastObject = result - return nil -} - -func (p *Plasma) pushOP(context *Context) *Value { - if context.LastObject != nil { - context.PushObject(context.LastObject) - context.LastObject = nil - } - return nil -} - -func (p *Plasma) assignIdentifierOP(context *Context, symbol string) *Value { - value := context.PopObject() - context.PeekSymbolTable().Set(symbol, value) - return nil -} - -func (p *Plasma) newClassOP(context *Context, classInformation ClassInformation) *Value { - bases := context.PopObject() - body := classInformation.Body - result := p.NewType(context, false, classInformation.Name, context.PeekSymbolTable(), bases.Content, - NewPlasmaConstructor(body), - ) - context.LastObject = result - return nil -} - -func (p *Plasma) newClassFunctionOP(context *Context, functionInformation FunctionInformation) *Value { - body := functionInformation.Body - context.LastObject = p.NewFunction( - context, - false, - context.PeekObject().SymbolTable().Parent, - NewPlasmaClassFunction( - context.PeekObject(), - functionInformation.NumberOfArguments, - body, - ), - ) - return nil -} - -func (p *Plasma) newFunctionOP(context *Context, functionInformation FunctionInformation) *Value { - body := functionInformation.Body - context.LastObject = p.NewFunction( - context, - false, - context.PeekSymbolTable(), - NewPlasmaFunction( - functionInformation.NumberOfArguments, - body, - ), - ) - return nil -} - -func (p *Plasma) loadFunctionArgumentsOP(context *Context, receivers []string) *Value { - for _, receiver := range receivers { - context.PeekSymbolTable().Set(receiver, context.PopObject()) - } - return nil -} - -func (p *Plasma) returnOP(context *Context, numberOfResults int) *Value { - // fmt.Println("Number of results:", numberOfResults) - if numberOfResults == 0 { - return p.GetNone() - } else if numberOfResults == 1 { - return context.PopObject() - } - resultValues := make([]*Value, numberOfResults) - for i := 0; i < numberOfResults; i++ { - resultValues[i] = context.PopObject() - } - return p.NewTuple(context, false, resultValues) -} - -func (p *Plasma) ifOneLinerOP(context *Context, information ConditionInformation) *Value { - condition := context.PopObject() - ifBody := information.Body - elseBody := information.ElseBody - asBool, asBoolError := p.QuickGetBool(context, condition) - if asBoolError != nil { - return asBoolError - } - var codeToExecute []*Code - if asBool { - codeToExecute = ifBody - } else { - codeToExecute = elseBody - } - result, success := p.Execute(context, NewBytecodeFromArray(codeToExecute)) - if !success { - return result - } - context.LastObject = result - return nil -} - -func (p *Plasma) unlessOneLinerOP(context *Context, information ConditionInformation) *Value { - condition := context.PopObject() - unlessBody := information.Body - elseBody := information.ElseBody - asBool, asBoolError := p.QuickGetBool(context, condition) - if asBoolError != nil { - return asBoolError - } - var codeToExecute []*Code - if !asBool { - codeToExecute = unlessBody - } else { - codeToExecute = elseBody - } - result, success := p.Execute(context, NewBytecodeFromArray(codeToExecute)) - if !success { - return result - } - context.LastObject = result - return nil -} - -func (p *Plasma) assignSelectorOP(context *Context, symbol string) *Value { - source := context.PopObject() - value := context.PopObject() - source.Set(p, context, symbol, value) - return nil -} - -func (p *Plasma) assignIndexOP(context *Context) *Value { - index := context.PopObject() - source := context.PopObject() - value := context.PopObject() - assign, getError := source.Get(p, context, Assign) - if getError != nil { - return getError - } - result, success := p.CallFunction(context, assign, index, value) - if !success { - return result - } - return nil -} - -func (p *Plasma) ifOP(context *Context, information ConditionInformation) *Value { - condition := context.PopObject() - ifBody := information.Body - elseBody := information.ElseBody - conditionAsBool, transformationError := p.QuickGetBool(context, condition) - if transformationError != nil { - return transformationError - } - var codeToExecute []*Code - if conditionAsBool { - codeToExecute = ifBody - } else { - codeToExecute = elseBody - } - result, success := p.Execute(context, NewBytecodeFromArray(codeToExecute)) - if !success { - return result - } - context.LastObject = result - return nil -} - -func (p *Plasma) unlessOP(context *Context, information ConditionInformation) *Value { - condition := context.PopObject() - ifBody := information.Body - elseBody := information.ElseBody - conditionAsBool, transformationError := p.QuickGetBool(context, condition) - if transformationError != nil { - return transformationError - } - var codeToExecute []*Code - if !conditionAsBool { - codeToExecute = ifBody - } else { - codeToExecute = elseBody - } - result, success := p.Execute(context, NewBytecodeFromArray(codeToExecute)) - if !success { - return result - } - context.LastObject = result - return nil -} - -func (p *Plasma) forLoopOP(context *Context, information LoopInformation) *Value { - source, success := p.InterpretAsIterator(context, context.PopObject()) - if !success { - return source - } - next, nextGetError := source.Get(p, context, Next) - if nextGetError != nil { - return nextGetError - } - hasNext, hasNextGetError := source.Get(p, context, HasNext) - if hasNextGetError != nil { - return hasNextGetError - } - body := information.Body - numberOfReceivers := len(information.Receivers) - bodyBytecode := NewBytecodeFromArray(body) - var ( - doesHasNext *Value - nextValue *Value - result *Value - ) -loop: - for { - continueState: - // Check if the iter has a next value - doesHasNext, success = p.CallFunction(context, hasNext) - if !success { - return doesHasNext - } - doesHasNextAsBool, boolInterpretationError := p.QuickGetBool(context, doesHasNext) - if boolInterpretationError != nil { - return boolInterpretationError - } - if !doesHasNextAsBool { - break - } - - // Get the value - nextValue, success = p.CallFunction(context, next) - if !success { - return nextValue - } - redoState: - // Unpack the value - unpackedValues, unpackError := p.UnpackValues(context, nextValue, numberOfReceivers) - if unpackError != nil { - return unpackError - } - numberOfUnpackedValues := len(unpackedValues) - if numberOfUnpackedValues != numberOfReceivers { - return p.NewIndexOutOfRange(context, numberOfUnpackedValues, int64(numberOfReceivers)) - } - for index, symbol := range information.Receivers { - context.PeekSymbolTable().Set(symbol, unpackedValues[index]) - } - // Reset the bytecode - bodyBytecode.index = 0 - // Execute the body - result, success = p.Execute(context, bodyBytecode) - if !success { - return result - } - switch context.LastState { - case ReturnState: - context.LastObject = result - return nil - case BreakState: - break loop - case ContinueState: - goto continueState - case RedoState: - goto redoState - } - } - context.LastState = NoState - return nil -} - -func (p *Plasma) newGeneratorOP(context *Context, numberOfReceivers int) *Value { - operation := context.PopObject() - source := context.PopObject() - sourceAsIter, interpretationSuccess := p.InterpretAsIterator(context, source) - if !interpretationSuccess { - return sourceAsIter - } - sourceAsIterHasNext, hasNextError := sourceAsIter.Get(p, context, HasNext) - if hasNextError != nil { - return hasNextError - } - sourceAsIterNext, nextGetError := sourceAsIter.Get(p, context, Next) - if nextGetError != nil { - return nextGetError - } - result := p.NewIterator(context, false) - result.SetOnDemandSymbol( - HasNext, - func() *Value { - return p.NewFunction(context, false, result.SymbolTable(), - NewBuiltInFunction(0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.CallFunction(context, sourceAsIterHasNext) - }, - ), - ) - }, - ) - result.SetOnDemandSymbol( - Next, - func() *Value { - return p.NewFunction(context, false, result.SymbolTable(), - NewBuiltInFunction(0, - func(self *Value, _ ...*Value) (*Value, bool) { - nextValues, success := p.CallFunction(context, sourceAsIterNext) - if !success { - return nextValues, false - } - unpackedValues, unpackError := p.UnpackValues(context, nextValues, numberOfReceivers) - if unpackError != nil { - return unpackError, false - } - return p.CallFunction(context, operation, unpackedValues...) - }, - ), - ) - }, - ) - context.LastObject = result - return nil -} - -func (p *Plasma) whileLoopOP(context *Context, information LoopInformation) *Value { - conditionCode := information.Condition - conditionBytecode := NewBytecodeFromArray(conditionCode) - - body := information.Body - bodyBytecode := NewBytecodeFromArray(body) - - var ( - result *Value - ) -loop: - for { - continueState: - // Reset condition bytecode - conditionBytecode.index = 0 - // Check the condition - condition, success := p.Execute(context, conditionBytecode) - if !success { - return condition - } - // Interpret as boolean - conditionAsBool, interpretationError := p.QuickGetBool(context, condition) - if interpretationError != nil { - return interpretationError - } - if !conditionAsBool { - break - } - redoState: - // Reset the bytecode - bodyBytecode.index = 0 - // Execute the body - result, success = p.Execute(context, bodyBytecode) - if !success { - return result - } - switch context.LastState { - case ReturnState: - context.LastObject = result - return nil - case BreakState: - break loop - case ContinueState: - goto continueState - case RedoState: - goto redoState - } - } - context.LastState = NoState - return nil -} - -func (p *Plasma) doWhileLoopOP(context *Context, information LoopInformation) *Value { - conditionCode := information.Condition - conditionBytecode := NewBytecodeFromArray(conditionCode) - - body := information.Body - bodyBytecode := NewBytecodeFromArray(body) - - var ( - condition *Value - ) -loop: - for { - redoState: - // Execute code - // Reset the bytecode - bodyBytecode.index = 0 - // Execute the body - result, success := p.Execute(context, bodyBytecode) - if !success { - return result - } - // Check state - switch context.LastState { - case ReturnState: - context.LastObject = result - return nil - case BreakState: - break loop - case RedoState: - goto redoState - } - // Reset condition bytecode - conditionBytecode.index = 0 - // Check the condition - condition, success = p.Execute(context, conditionBytecode) - if !success { - return condition - } - // Interpret as boolean - conditionAsBool, interpretationError := p.QuickGetBool(context, condition) - if interpretationError != nil { - return interpretationError - } - if !conditionAsBool { - break - } - } - context.LastState = NoState - return nil -} - -func (p *Plasma) untilLoopOP(context *Context, information LoopInformation) *Value { - conditionCode := information.Condition - conditionBytecode := NewBytecodeFromArray(conditionCode) - - bodyBytecode := NewBytecodeFromArray(information.Body) - - var ( - result *Value - ) -loop: - for { - continueState: - // Reset condition bytecode - conditionBytecode.index = 0 - // Check the condition - condition, success := p.Execute(context, conditionBytecode) - if !success { - return condition - } - // Interpret as boolean - conditionAsBool, interpretationError := p.QuickGetBool(context, condition) - if interpretationError != nil { - return interpretationError - } - if conditionAsBool { - break - } - redoState: - // Reset the bytecode - bodyBytecode.index = 0 - // Execute the body - result, success = p.Execute(context, bodyBytecode) - if !success { - return result - } - switch context.LastState { - case ReturnState: - context.LastObject = result - return nil - case BreakState: - break loop - case ContinueState: - goto continueState - case RedoState: - goto redoState - } - } - context.LastState = NoState - return nil -} - -func (p *Plasma) finallyOP(context *Context, finally []*Code) *Value { - if finally == nil { - return nil - } - result, success := p.Execute(context, NewBytecodeFromArray(finally)) - if !success { - return result - } - context.NoState() - return nil -} - -func (p *Plasma) tryOP(context *Context, information TryInformation) *Value { - tryBytecode := NewBytecodeFromArray(information.Body) - result, success := p.Execute(context, tryBytecode) - if success { - finallyExecutionError := p.finallyOP(context, information.Finally) - if finallyExecutionError != nil { - return finallyExecutionError - } - if context.LastState == ReturnState { - context.LastObject = result - } - return nil - } - errorClass := result.GetClass(p) - for _, except := range information.Excepts { - var targetsTuple *Value - targetsTuple, success = p.Execute(context, NewBytecodeFromArray(except.Targets)) - if !success { - return targetsTuple - } - context.NoState() - if len(targetsTuple.Content) > 0 { - found := false - for _, target := range targetsTuple.Content { - if errorClass.Implements(target) { - found = true - break - } - } - if !found { - continue - } - if except.CaptureName != "" { - context.PeekSymbolTable().Set(except.CaptureName, result) - } - } - var exceptResult *Value - exceptResult, success = p.Execute(context, NewBytecodeFromArray(except.Body)) - if !success { - return exceptResult - } - finallyExecutionError := p.finallyOP(context, information.Finally) - if finallyExecutionError != nil { - return finallyExecutionError - } - if context.LastState == ReturnState { - context.LastObject = exceptResult - } - return nil - } - context.NoState() - return result -} - -func (p *Plasma) newModuleOP(context *Context, information ClassInformation) *Value { - result := p.NewModule(context, false) - context.PushSymbolTable(result.SymbolTable()) - executionError, success := p.Execute(context, NewBytecodeFromArray(information.Body)) - if !success { - return executionError - } - context.PopSymbolTable() - context.LastObject = result - return nil -} - -func (p *Plasma) switchOP(context *Context, information SwitchInformation) *Value { - reference := context.PopObject() - for _, caseBlock := range information.Cases { - targets, success := p.Execute(context, NewBytecodeFromArray(caseBlock.Targets)) - if !success { - return targets - } - var contains *Value - contains, success = p.ContentContains(context, targets, reference) - if !success { - return contains - } - if !contains.Bool { - continue - } - var result *Value - result, success = p.Execute(context, NewBytecodeFromArray(caseBlock.Body)) - if !success { - return result - } - context.LastObject = result - return nil - } - // Execute Default - if information.Default == nil { - return nil - } - result, success := p.Execute(context, NewBytecodeFromArray(information.Default)) - if !success { - return result - } - context.LastObject = result - return nil -} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/vm/integer.go b/vendor/github.com/shoriwe/gplasma/pkg/vm/integer.go index c3f0c06..3ceb29a 100644 --- a/vendor/github.com/shoriwe/gplasma/pkg/vm/integer.go +++ b/vendor/github.com/shoriwe/gplasma/pkg/vm/integer.go @@ -1,874 +1,396 @@ package vm import ( - "fmt" - "github.com/shoriwe/gplasma/pkg/tools" + "bytes" + "encoding/binary" + magic_functions "github.com/shoriwe/gplasma/pkg/common/magic-functions" "math" ) -func (p *Plasma) NewInteger(context *Context, isBuiltIn bool, value int64) *Value { - integer := p.NewValue(context, isBuiltIn, IntegerName, nil, context.PeekSymbolTable()) - integer.BuiltInTypeId = IntegerId - integer.Integer = value - p.IntegerInitialize(isBuiltIn)(context, integer) - integer.SetOnDemandSymbol(Self, - func() *Value { - return integer - }, - ) - return integer +func (plasma *Plasma) integerClass() *Value { + class := plasma.NewValue(plasma.rootSymbols, BuiltInClassId, plasma.class) + class.SetAny(Callback(func(argument ...*Value) (*Value, error) { + return plasma.NewInt(argument[0].Int()), nil + })) + return class } -func (p *Plasma) IntegerInitialize(isBuiltIn bool) ConstructorCallBack { - return func(context *Context, object *Value) *Value { - object.SetOnDemandSymbol(NegateBits, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.NewInteger(context, false, - ^self.Integer, - ), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Negative, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.NewInteger(context, false, - -self.Integer, - ), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Add, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - right := arguments[0] - switch right.BuiltInTypeId { - case IntegerId: - return p.NewInteger(context, false, - self.Integer+right.Integer, - ), true - case FloatId: - return p.NewFloat(context, false, - float64(self.Integer)+right.Float, - ), true - default: - return p.NewInvalidTypeError(context, right.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightAdd, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - left := arguments[0] - switch left.BuiltInTypeId { - case IntegerId: - return p.NewInteger(context, false, - left.Integer+self.Integer, - ), true - case FloatId: - return p.NewFloat(context, false, - left.Float+float64(self.Integer), - ), true - default: - return p.NewInvalidTypeError(context, left.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Sub, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - right := arguments[0] - switch right.BuiltInTypeId { - case IntegerId: - return p.NewInteger(context, false, - self.Integer-right.Integer, - ), true - case FloatId: - return p.NewFloat(context, false, - float64(self.Integer)-right.Float, - ), true - default: - return p.NewInvalidTypeError(context, right.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightSub, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - left := arguments[0] - switch left.BuiltInTypeId { - case IntegerId: - return p.NewInteger(context, false, - left.Integer-self.Integer, - ), true - case FloatId: - return p.NewFloat(context, false, - left.Float-float64(self.Integer), - ), true - default: - return p.NewInvalidTypeError(context, left.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Mul, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - right := arguments[0] - switch right.BuiltInTypeId { - case IntegerId: - return p.NewInteger(context, false, - self.Integer*right.Integer, - ), true - case FloatId: - return p.NewFloat(context, false, - float64(self.Integer)*right.Float, - ), true - case StringId: - return p.NewString(context, false, tools.Repeat(right.String, self.Integer)), true - case BytesId: - content, repetitionError := p.Repeat(context, right.Content, self.Integer) - if repetitionError != nil { - return repetitionError, false - } - return p.NewTuple(context, false, content), true - case ArrayId: - content, repetitionError := p.Repeat(context, right.Content, self.Integer) - if repetitionError != nil { - return repetitionError, false - } - return p.NewArray(context, false, content), true - default: - return p.NewInvalidTypeError(context, right.TypeName(), IntegerName, FloatName, StringName, ArrayName, TupleName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightMul, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - left := arguments[0] - switch left.BuiltInTypeId { - case IntegerId: - return p.NewInteger(context, false, - left.Integer*self.Integer, - ), true - case FloatId: - return p.NewFloat(context, false, - left.Float*float64(self.Integer), - ), true - case StringId: - return p.NewString(context, false, tools.Repeat(left.String, self.Integer)), true - case BytesId: - content, repetitionError := p.Repeat(context, left.Content, self.Integer) - if repetitionError != nil { - return repetitionError, false - } - return p.NewTuple(context, false, content), true - case ArrayId: - content, repetitionError := p.Repeat(context, left.Content, self.Integer) - if repetitionError != nil { - return repetitionError, false - } - return p.NewArray(context, false, content), true - default: - return p.NewInvalidTypeError(context, left.TypeName(), IntegerName, FloatName, StringName, ArrayName, TupleName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Div, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - right := arguments[0] - switch right.BuiltInTypeId { - case IntegerId: - return p.NewFloat(context, false, - float64(self.Integer)/float64(right.Integer), - ), true - case FloatId: - return p.NewFloat(context, false, - float64(self.Integer)/right.Float, - ), true - default: - return p.NewInvalidTypeError(context, right.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightDiv, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - left := arguments[0] - switch left.BuiltInTypeId { - case IntegerId: - return p.NewFloat(context, false, - float64(left.Integer)/float64(self.Integer), - ), true - case FloatId: - return p.NewFloat(context, false, - left.Float/float64(self.Integer), - ), true - default: - return p.NewInvalidTypeError(context, left.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(FloorDiv, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - right := arguments[0] - switch right.BuiltInTypeId { - case IntegerId: - return p.NewInteger(context, false, - self.Integer/right.Integer, - ), true - case FloatId: - return p.NewInteger(context, false, - self.Integer/int64(right.Float), - ), true - default: - return p.NewInvalidTypeError(context, right.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightFloorDiv, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - left := arguments[0] - switch left.BuiltInTypeId { - case IntegerId: - return p.NewInteger(context, false, - left.Integer/self.Integer, - ), true - case FloatId: - return p.NewInteger(context, false, - int64(left.Float)/self.Integer, - ), true - default: - return p.NewInvalidTypeError(context, left.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Mod, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - right := arguments[0] - switch right.BuiltInTypeId { - case IntegerId: - return p.NewFloat(context, false, - math.Mod(float64(self.Integer), float64(right.Integer)), - ), true - case FloatId: - return p.NewFloat(context, false, - math.Mod(float64(self.Integer), right.Float), - ), true - default: - return p.NewInvalidTypeError(context, right.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightMod, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - left := arguments[0] - switch left.BuiltInTypeId { - case IntegerId: - return p.NewInteger(context, false, - left.Integer%self.Integer, - ), true - case FloatId: - return p.NewInteger(context, false, - int64(left.Float)%self.Integer, - ), true - default: - return p.NewInvalidTypeError(context, left.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Pow, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - right := arguments[0] - switch right.BuiltInTypeId { - case IntegerId: - return p.NewFloat(context, false, - math.Pow(float64(self.Integer), float64(right.Integer)), - ), true - case FloatId: - return p.NewFloat(context, false, - math.Pow(float64(self.Integer), right.Float), - ), true - default: - return p.NewInvalidTypeError(context, right.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightPow, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - left := arguments[0] - switch left.BuiltInTypeId { - case IntegerId: - return p.NewFloat(context, false, - math.Pow( - float64(left.Integer), - float64(self.Integer), - ), - ), true - case FloatId: - return p.NewFloat(context, false, - math.Pow( - left.Float, - float64(self.Integer), - ), - ), true - default: - return p.NewInvalidTypeError(context, left.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(BitXor, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - right := arguments[0] - if !right.IsTypeById(BytesId) { - return p.NewInvalidTypeError(context, right.TypeName(), IntegerName), false - } - return p.NewInteger(context, false, - self.Integer^right.Integer, - ), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightBitXor, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - left := arguments[0] - if !left.IsTypeById(IntegerId) { - return p.NewInvalidTypeError(context, left.TypeName(), IntegerName), false - } - return p.NewInteger(context, false, - left.Integer^self.Integer, - ), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(BitAnd, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - right := arguments[0] - if !right.IsTypeById(BytesId) { - return p.NewInvalidTypeError(context, right.TypeName(), IntegerName), false - } - return p.NewInteger(context, false, - self.Integer&right.Integer, - ), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightBitAnd, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - left := arguments[0] - if !left.IsTypeById(IntegerId) { - return p.NewInvalidTypeError(context, left.TypeName(), IntegerName), false - } - return p.NewInteger(context, false, - left.Integer&self.Integer, - ), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(BitOr, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - right := arguments[0] - if !right.IsTypeById(BytesId) { - return p.NewInvalidTypeError(context, right.TypeName(), IntegerName), false - } - return p.NewInteger(context, false, - self.Integer|right.Integer, - ), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightBitOr, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - left := arguments[0] - if !left.IsTypeById(IntegerId) { - return p.NewInvalidTypeError(context, left.TypeName(), IntegerName), false - } - return p.NewInteger(context, false, - left.Integer|self.Integer, - ), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(BitLeft, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - right := arguments[0] - if !right.IsTypeById(BytesId) { - return p.NewInvalidTypeError(context, right.TypeName(), IntegerName), false - } - return p.NewInteger(context, false, - self.Integer<>uint(right.Integer), - ), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightBitRight, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - left := arguments[0] - if !left.IsTypeById(IntegerId) { - return p.NewInvalidTypeError(context, left.TypeName(), IntegerName), false - } - return p.NewInteger(context, false, - left.Integer>>uint(self.Integer), - ), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Equals, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - right := arguments[0] - switch right.BuiltInTypeId { - case IntegerId: - return p.InterpretAsBool(self.Integer == right.Integer), true - case FloatId: - return p.InterpretAsBool(float64(self.Integer) == right.Float), true - default: - return p.NewInvalidTypeError(context, right.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightEquals, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - left := arguments[0] - switch left.BuiltInTypeId { - case IntegerId: - return p.InterpretAsBool(left.Integer == self.Integer), true - case FloatId: - return p.InterpretAsBool(left.Float == float64(self.Integer)), true - default: - return p.NewInvalidTypeError(context, left.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(NotEquals, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - right := arguments[0] - switch right.BuiltInTypeId { - case IntegerId: - return p.InterpretAsBool(self.Integer != right.Integer), true - case FloatId: - return p.InterpretAsBool(float64(self.Integer) != (right.Float)), true - default: - return p.NewInvalidTypeError(context, right.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightNotEquals, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - left := arguments[0] - switch left.BuiltInTypeId { - case IntegerId: - return p.InterpretAsBool(left.Integer != self.Integer), true - case FloatId: - return p.InterpretAsBool(left.Float != float64(self.Integer)), true - default: - return p.NewInvalidTypeError(context, left.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(GreaterThan, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - right := arguments[0] - switch right.BuiltInTypeId { - case IntegerId: - return p.InterpretAsBool(self.Integer > right.Integer), true - case FloatId: - return p.InterpretAsBool(float64(self.Integer) > right.Float), true - default: - return p.NewInvalidTypeError(context, right.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightGreaterThan, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - left := arguments[0] - switch left.BuiltInTypeId { - case IntegerId: - return p.InterpretAsBool(left.Integer > self.Integer), true - case FloatId: - return p.InterpretAsBool(left.Float > float64(self.Integer)), true - default: - return p.NewInvalidTypeError(context, left.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(LessThan, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - right := arguments[0] - switch right.BuiltInTypeId { - case IntegerId: - return p.InterpretAsBool(self.Integer < right.Integer), true - case FloatId: - return p.InterpretAsBool(float64(self.Integer) < right.Float), true - default: - return p.NewInvalidTypeError(context, right.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightLessThan, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - left := arguments[0] - switch left.BuiltInTypeId { - case IntegerId: - return p.InterpretAsBool(left.Integer < self.Integer), true - case FloatId: - return p.InterpretAsBool(left.Float < float64(self.Integer)), true - default: - return p.NewInvalidTypeError(context, left.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(GreaterThanOrEqual, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - right := arguments[0] - switch right.BuiltInTypeId { - case IntegerId: - return p.InterpretAsBool(self.Integer >= right.Integer), true - case FloatId: - return p.InterpretAsBool(float64(self.Integer) >= right.Float), true - default: - return p.NewInvalidTypeError(context, right.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightGreaterThanOrEqual, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - left := arguments[0] - switch left.BuiltInTypeId { - case IntegerId: - return p.InterpretAsBool(left.Integer >= self.Integer), true - case FloatId: - return p.InterpretAsBool(left.Float >= float64(self.Integer)), true - default: - return p.NewInvalidTypeError(context, left.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(LessThanOrEqual, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - right := arguments[0] - switch right.BuiltInTypeId { - case IntegerId: - return p.InterpretAsBool(self.Integer <= right.Integer), true - case FloatId: - return p.InterpretAsBool(float64(self.Integer) <= right.Float), true - default: - return p.NewInvalidTypeError(context, right.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightLessThanOrEqual, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - left := arguments[0] - switch left.BuiltInTypeId { - case IntegerId: - return p.InterpretAsBool(left.Integer <= self.Integer), true - case FloatId: - return p.InterpretAsBool(left.Float <= float64(self.Integer)), true - default: - return p.NewInvalidTypeError(context, left.TypeName(), IntegerName, FloatName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Hash, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.NewInteger(context, false, self.Integer), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Copy, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.NewInteger(context, false, self.Integer), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(ToInteger, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.NewInteger(context, false, self.Integer), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(ToFloat, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.NewFloat(context, false, - float64(self.Integer), - ), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(ToString, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.NewString(context, false, fmt.Sprint(self.Integer)), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(ToBool, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.InterpretAsBool(self.Integer != 0), true - }, - ), - ) - }, - ) - return nil - } +/* +NewInt magic function: +Positive: __positive__ +Negative: __negative__ +NegateBits: __negate_its__ +Equal: __equal__ +NotEqual: __not_equal__ +GreaterThan: __greater_than__ +GreaterOrEqualThan: __greater_or_equal_than__ +LessThan: __less_than__ +LessOrEqualThan: __less_or_equal_than__ +BitwiseOr: __bitwise_or__ +BitwiseXor: __bitwise_xor__ +BitwiseAnd: __bitwise_and__ +BitwiseLeft: __bitwise_left__ +BitwiseRight: __bitwise_right__ +Add: __add__ +Sub: __sub__ +Mul: __mul__ +Div: __div__ +FloorDiv: __floor_div__ +Modulus: __mod__ +PowerOf: __pow__ +Bool: __bool__ +String __string__ +Int __int__ +Float __float__ +Copy: __copy__ +BigEndian big_endian +LittleEndian little_endian +FromBig from_big +FromLittle from_little +*/ +func (plasma *Plasma) NewInt(i int64) *Value { + result := plasma.NewValue(plasma.rootSymbols, IntId, plasma.int) + result.SetAny(i) + result.Set(magic_functions.Positive, + plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return result, nil + }, + )) + result.Set(magic_functions.Negative, + plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewInt(-result.GetInt64()), nil + }, + )) + result.Set(magic_functions.NegateBits, + plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewInt(^result.GetInt64()), nil + }, + )) + result.Set(magic_functions.Equal, + plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case IntId, FloatId: + return plasma.NewBool(result.Equal(argument[0])), nil + } + return plasma.false, nil + }, + )) + result.Set(magic_functions.NotEqual, + plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case IntId, FloatId: + return plasma.NewBool(!result.Equal(argument[0])), nil + } + return plasma.true, nil + }, + )) + result.Set(magic_functions.GreaterThan, + plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case IntId: + return plasma.NewBool(result.Int() > argument[0].Int()), nil + case FloatId: + return plasma.NewBool(result.Float() > argument[0].Float()), nil + } + return nil, NotComparable + }, + )) + result.Set(magic_functions.GreaterOrEqualThan, + plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case IntId: + return plasma.NewBool(result.Int() >= argument[0].Int()), nil + case FloatId: + return plasma.NewBool(result.Float() >= argument[0].Float()), nil + } + return nil, NotComparable + }, + )) + result.Set(magic_functions.LessThan, + plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case IntId: + return plasma.NewBool(result.Int() < argument[0].Int()), nil + case FloatId: + return plasma.NewBool(result.Float() < argument[0].Float()), nil + } + return nil, NotComparable + }, + )) + result.Set(magic_functions.LessOrEqualThan, + plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case IntId: + return plasma.NewBool(result.Int() <= argument[0].Int()), nil + case FloatId: + return plasma.NewBool(result.Float() <= argument[0].Float()), nil + } + return nil, NotComparable + }, + )) + result.Set(magic_functions.BitwiseOr, + plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case IntId: + return plasma.NewInt(result.Int() | argument[0].Int()), nil + case FloatId: + return plasma.NewInt(int64(uint64(result.Int()) | math.Float64bits(argument[0].Float()))), nil + } + return nil, NotOperable + }, + )) + result.Set(magic_functions.BitwiseXor, + plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case IntId: + return plasma.NewInt(result.Int() ^ argument[0].Int()), nil + case FloatId: + return plasma.NewInt(int64(uint64(result.Int()) ^ math.Float64bits(argument[0].Float()))), nil + } + return nil, NotOperable + }, + )) + result.Set(magic_functions.BitwiseAnd, + plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case IntId: + return plasma.NewInt(result.Int() & argument[0].Int()), nil + case FloatId: + return plasma.NewInt(int64(uint64(result.Int()) & math.Float64bits(argument[0].Float()))), nil + } + return nil, NotOperable + }, + )) + result.Set(magic_functions.BitwiseLeft, + plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case IntId: + return plasma.NewInt(result.Int() << argument[0].Int()), nil + case FloatId: + return plasma.NewInt(int64(uint64(result.Int()) << math.Float64bits(argument[0].Float()))), nil + } + return nil, NotOperable + }, + )) + result.Set(magic_functions.BitwiseRight, + plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case IntId: + return plasma.NewInt(result.Int() >> argument[0].Int()), nil + case FloatId: + return plasma.NewInt(int64(uint64(result.Int()) >> math.Float64bits(argument[0].Float()))), nil + } + return nil, NotOperable + }, + )) + result.Set(magic_functions.Add, + plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case IntId: + return plasma.NewInt(result.Int() + argument[0].Int()), nil + case FloatId: + return plasma.NewFloat(result.Float() + argument[0].Float()), nil + } + return nil, NotOperable + }, + )) + result.Set(magic_functions.Sub, + plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case IntId: + return plasma.NewInt(result.Int() - argument[0].Int()), nil + case FloatId: + return plasma.NewFloat(result.Float() - argument[0].Float()), nil + } + return nil, NotOperable + }, + )) + result.Set(magic_functions.Mul, + plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case IntId: + return plasma.NewInt(result.Int() * argument[0].Int()), nil + case FloatId: + return plasma.NewFloat(result.Float() * argument[0].Float()), nil + case StringId: + s := argument[0].GetBytes() + times := result.GetInt64() + return plasma.NewString(bytes.Repeat(s, int(times))), nil + case BytesId: + s := argument[0].GetBytes() + times := result.GetInt64() + return plasma.NewBytes(bytes.Repeat(s, int(times))), nil + case ArrayId: + times := result.GetInt64() + currentValues := argument[0].GetValues() + newValues := make([]*Value, 0, int64(len(currentValues))*times) + for t := int64(0); t < times; t++ { + for _, value := range currentValues { + newValues = append(newValues, value) + } + } + return plasma.NewArray(newValues), nil + } + return nil, NotOperable + }, + )) + result.Set(magic_functions.Div, + plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case IntId, FloatId: + return plasma.NewFloat(result.Float() / argument[0].Float()), nil + } + return nil, NotOperable + }, + )) + result.Set(magic_functions.FloorDiv, + plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case IntId, FloatId: + return plasma.NewInt(result.Int() / argument[0].Int()), nil + } + return nil, NotOperable + }, + )) + result.Set(magic_functions.Modulus, + plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case IntId: + return plasma.NewInt(result.Int() % argument[0].Int()), nil + case FloatId: + return plasma.NewFloat(math.Mod(result.Float(), argument[0].Float())), nil + } + return nil, NotOperable + }, + )) + result.Set(magic_functions.PowerOf, + plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case IntId: + times := argument[0].Int() + value := result.Int() + if times >= 0 { + v := int64(1) + for t := int64(0); t < times; t++ { + v *= value + } + return plasma.NewInt(v), nil + } + v := int64(1) + for t := int64(0); times < t; t-- { + v *= value + } + return plasma.NewFloat(1 / float64(v)), nil + case FloatId: + return plasma.NewFloat(math.Pow(result.Float(), argument[0].Float())), nil + } + return nil, NotOperable + }, + )) + result.Set(magic_functions.Bool, + plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewBool(result.GetInt64() != 0), nil + }, + )) + result.Set(magic_functions.String, + plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewString([]byte(result.String())), nil + }, + )) + result.Set(magic_functions.Int, + plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return result, nil + }, + )) + result.Set(magic_functions.Float, + plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewFloat(result.Float()), nil + }, + )) + result.Set(magic_functions.Copy, + plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewInt(result.GetInt64()), nil + }, + )) + result.Set(magic_functions.BigEndian, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + b := make([]byte, 8) + binary.BigEndian.PutUint64(b, uint64(result.Int())) + return plasma.NewBytes(b), nil + }, + )) + result.Set(magic_functions.LittleEndian, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + b := make([]byte, 8) + binary.LittleEndian.PutUint64(b, uint64(result.Int())) + return plasma.NewBytes(b), nil + }, + )) + result.Set(magic_functions.FromBig, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewInt(int64(binary.BigEndian.Uint64(argument[0].GetBytes()))), nil + }, + )) + result.Set(magic_functions.FromLittle, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewInt(int64(binary.LittleEndian.Uint64(argument[0].GetBytes()))), nil + }, + )) + return result } diff --git a/vendor/github.com/shoriwe/gplasma/pkg/vm/iterator.go b/vendor/github.com/shoriwe/gplasma/pkg/vm/iterator.go deleted file mode 100644 index 1fd8a61..0000000 --- a/vendor/github.com/shoriwe/gplasma/pkg/vm/iterator.go +++ /dev/null @@ -1,74 +0,0 @@ -package vm - -func (p *Plasma) NewIterator(context *Context, isBuiltIn bool) *Value { - iterator := p.NewValue(context, isBuiltIn, IteratorName, nil, context.PeekSymbolTable()) - iterator.BuiltInTypeId = IteratorId - p.IteratorInitialize(isBuiltIn)(context, iterator) - iterator.SetOnDemandSymbol(Self, - func() *Value { - return iterator - }, - ) - return iterator -} - -func (p *Plasma) IteratorInitialize(isBuiltIn bool) ConstructorCallBack { - return func(context *Context, object *Value) *Value { - object.SetOnDemandSymbol(HasNext, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(_ *Value, _ ...*Value) (*Value, bool) { - return p.GetFalse(), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Next, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(_ *Value, _ ...*Value) (*Value, bool) { - return p.GetNone(), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Iter, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return self, true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(ToTuple, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.IterToContent(context, self, TupleId) - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(ToArray, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.IterToContent(context, self, ArrayId) - }, - ), - ) - }, - ) - return nil - } -} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/vm/module.go b/vendor/github.com/shoriwe/gplasma/pkg/vm/module.go deleted file mode 100644 index aec9b6b..0000000 --- a/vendor/github.com/shoriwe/gplasma/pkg/vm/module.go +++ /dev/null @@ -1,12 +0,0 @@ -package vm - -func (p *Plasma) NewModule(context *Context, isBuiltIn bool) *Value { - module := p.NewValue(context, isBuiltIn, ModuleName, nil, context.PeekSymbolTable()) - module.BuiltInTypeId = ModuleId - module.SetOnDemandSymbol(Self, - func() *Value { - return module - }, - ) - return module -} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/vm/none.go b/vendor/github.com/shoriwe/gplasma/pkg/vm/none.go index 125c511..79981ff 100644 --- a/vendor/github.com/shoriwe/gplasma/pkg/vm/none.go +++ b/vendor/github.com/shoriwe/gplasma/pkg/vm/none.go @@ -1,69 +1,36 @@ package vm -func (p *Plasma) GetNone() *Value { - return p.ForceMasterGetAny(None) -} +import magic_functions "github.com/shoriwe/gplasma/pkg/common/magic-functions" -func (p *Plasma) NewNone(context *Context, isBuiltIn bool, parent *SymbolTable) *Value { - result := p.NewValue(context, isBuiltIn, NoneName, nil, parent) - result.BuiltInTypeId = NoneId - p.NoneInitialize(isBuiltIn)(context, result) - result.SetOnDemandSymbol(Self, - func() *Value { - return result - }, - ) - return result +func (plasma *Plasma) noneClass() *Value { + class := plasma.NewValue(plasma.rootSymbols, BuiltInClassId, plasma.class) + class.SetAny(Callback(func(argument ...*Value) (*Value, error) { + return plasma.NewNone(), nil + })) + return class } -func (p *Plasma) NoneInitialize(isBuiltIn bool) ConstructorCallBack { - return func(context *Context, object *Value) *Value { - object.SetOnDemandSymbol(Equals, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(_ *Value, arguments ...*Value) (*Value, bool) { - right := arguments[0] - return p.InterpretAsBool(right.IsTypeById(NoneId)), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(NotEquals, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(_ *Value, arguments ...*Value) (*Value, bool) { - left := arguments[0] - return p.InterpretAsBool(left.IsTypeById(NoneId)), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(ToString, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(_ *Value, _ ...*Value) (*Value, bool) { - return p.NewString(context, false, "None"), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(ToBool, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(_ *Value, _ ...*Value) (*Value, bool) { - return p.GetFalse(), true - }, - ), - ) - }, - ) - return nil +/* +NewNone magic function: +Bool __bool__ +String __string__ +*/ +func (plasma *Plasma) NewNone() *Value { + if plasma.none != nil { + return plasma.none } + result := plasma.NewValue(plasma.rootSymbols, NoneId, plasma.noneType) + result.Set(magic_functions.Bool, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.false, nil + }, + )) + result.Set(magic_functions.String, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewString([]byte(result.String())), nil + }, + )) + return result } diff --git a/vendor/github.com/shoriwe/gplasma/pkg/vm/op_codes.go b/vendor/github.com/shoriwe/gplasma/pkg/vm/op_codes.go deleted file mode 100644 index e1774b5..0000000 --- a/vendor/github.com/shoriwe/gplasma/pkg/vm/op_codes.go +++ /dev/null @@ -1,196 +0,0 @@ -package vm - -const ( - ReturnState uint8 = iota - BreakState - RedoState - ContinueState - NoState -) - -const ( - NewStringOP uint8 = iota - NewBytesOP - NewIntegerOP - NewFloatOP - GetTrueOP - GetFalseOP - GetNoneOP - NewTupleOP - NewArrayOP - NewHashOP - - UnaryOP - NegateBitsOP - BoolNegateOP - NegativeOP - - BinaryOP - AddOP - SubOP - MulOP - DivOP - FloorDivOP - ModOP - PowOP - BitXorOP - BitAndOP - BitOrOP - BitLeftOP - BitRightOP - AndOP - OrOP - XorOP - EqualsOP - NotEqualsOP - GreaterThanOP - LessThanOP - GreaterThanOrEqualOP - LessThanOrEqualOP - ContainsOP - - IfOP - IfOneLinerOP - UnlessOP - UnlessOneLinerOP - - GetIdentifierOP - IndexOP - SelectNameFromObjectOP - MethodInvocationOP - AssignIdentifierOP - AssignSelectorOP - AssignIndexOP - BreakOP - RedoOP - ContinueOP - ReturnOP - - ForLoopOP - WhileLoopOP - DoWhileLoopOP - UntilLoopOP - - NOP - - SwitchOP - - LoadFunctionArgumentsOP - NewFunctionOP - PushOP - NewGeneratorOP - TryOP - NewModuleOP - NewClassOP - NewClassFunctionOP - RaiseOP -) - -var unaryInstructionsFunctions = map[uint8]string{ - NegateBitsOP: NegateBits, - BoolNegateOP: Negate, - NegativeOP: Negative, -} - -var binaryInstructionsFunctions = map[uint8][2]string{ - AddOP: {Add, RightAdd}, - SubOP: {Sub, RightSub}, - MulOP: {Mul, RightMul}, - DivOP: {Div, RightDiv}, - FloorDivOP: {FloorDiv, RightFloorDiv}, - ModOP: {Mod, RightMod}, - PowOP: {Pow, RightPow}, - BitXorOP: {BitXor, RightBitXor}, - BitAndOP: {BitAnd, RightBitAnd}, - BitOrOP: {BitOr, RightBitOr}, - BitLeftOP: {BitLeft, RightBitLeft}, - BitRightOP: {BitRight, RightBitRight}, - AndOP: {And, RightAnd}, - OrOP: {Or, RightOr}, - XorOP: {Xor, RightXor}, - EqualsOP: {Equals, RightEquals}, - NotEqualsOP: {NotEquals, RightNotEquals}, - GreaterThanOP: {GreaterThan, RightGreaterThan}, - LessThanOP: {LessThan, RightLessThan}, - GreaterThanOrEqualOP: {GreaterThanOrEqual, RightGreaterThanOrEqual}, - LessThanOrEqualOP: {LessThanOrEqual, RightLessThanOrEqual}, - ContainsOP: {"029p3847980479087437891734", Contains}, -} - -var instructionNames = map[uint8]string{ - NewStringOP: "NewStringOP", - NewBytesOP: "NewBytesOP", - NewIntegerOP: "NewIntegerOP", - NewFloatOP: "NewFloatOP", - GetTrueOP: "GetTrueOP", - GetFalseOP: "GetFalseOP", - GetNoneOP: "GetNoneOP", - NewTupleOP: "NewTupleOP", - NewArrayOP: "NewArrayOP", - NewHashOP: "NewHashOP", - - UnaryOP: "UnaryOP", - NegateBitsOP: "NegateBitsOP", - BoolNegateOP: "BoolNegateOP", - NegativeOP: "NegativeOP", - - BinaryOP: "BinaryOP", - AddOP: "AddOP", - SubOP: "SubOP", - MulOP: "MulOP", - DivOP: "DivOP", - FloorDivOP: "FloorDivOP", - ModOP: "ModOP", - PowOP: "PowOP", - BitXorOP: "BitXorOP", - BitAndOP: "BitAndOP", - BitOrOP: "BitOrOP", - BitLeftOP: "BitLeftOP", - BitRightOP: "BitRightOP", - AndOP: "AndOP", - OrOP: "OrOP", - XorOP: "XorOP", - EqualsOP: "EqualsOP", - NotEqualsOP: "NotEqualsOP", - GreaterThanOP: "GreaterThanOP", - LessThanOP: "LessThanOP", - GreaterThanOrEqualOP: "GreaterThanOrEqualOP", - LessThanOrEqualOP: "LessThanOrEqualOP", - ContainsOP: "ContainsOP", - - IfOP: "IfOP", - IfOneLinerOP: "IfOneLinerOP", - UnlessOP: "UnlessOP", - UnlessOneLinerOP: "UnlessOneLinerOP", - - GetIdentifierOP: "GetIdentifierOP", - IndexOP: "IndexOP", - SelectNameFromObjectOP: "SelectNameFromObjectOP", - MethodInvocationOP: "MethodInvocationOP", - AssignIdentifierOP: "AssignIdentifierOP", - AssignSelectorOP: "AssignSelectorOP", - AssignIndexOP: "AssignIndexOP", - BreakOP: "BreakOP", - RedoOP: "RedoOP", - ContinueOP: "ContinueOP", - ReturnOP: "ReturnOP", - - ForLoopOP: "ForLoopOP", - WhileLoopOP: "WhileLoopOP", - DoWhileLoopOP: "DoWhileLoopOP", - UntilLoopOP: "UntilLoopOP", - - NOP: "NOP", - - SwitchOP: "SwitchOP", - - LoadFunctionArgumentsOP: "LoadFunctionArgumentsOP", - NewFunctionOP: "NewFunctionOP", - PushOP: "PushOP", - NewGeneratorOP: "NewGeneratorOP", - TryOP: "TryOP", - NewModuleOP: "NewModuleOP", - NewClassOP: "NewClassOP", - NewClassFunctionOP: "NewClassFunctionOP", - RaiseOP: "RaiseOP", -} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/vm/plasma.go b/vendor/github.com/shoriwe/gplasma/pkg/vm/plasma.go deleted file mode 100644 index a4b6e4a..0000000 --- a/vendor/github.com/shoriwe/gplasma/pkg/vm/plasma.go +++ /dev/null @@ -1,150 +0,0 @@ -package vm - -import ( - "bufio" - "crypto/rand" - "hash" - "hash/crc32" - "io" - "math/big" -) - -const ( - polySize = 0xffffffff -) - -type ( - ObjectLoader func(*Context, *Plasma) *Value - Feature map[string]ObjectLoader -) - -type Plasma struct { - currentId int64 - BuiltInContext *Context - Crc32Hash hash.Hash32 - seed uint64 - stdinScanner *bufio.Scanner - Stdin io.Reader - Stdout io.Writer - Stderr io.Writer -} - -func (p *Plasma) HashString(s string) int64 { - _, hashingError := p.Crc32Hash.Write([]byte(s)) - if hashingError != nil { - panic(hashingError) - } - hashValue := p.Crc32Hash.Sum32() - p.Crc32Hash.Reset() - return int64(hashValue) -} - -func (p *Plasma) HashBytes(s []byte) int64 { - _, hashingError := p.Crc32Hash.Write(s) - if hashingError != nil { - panic(hashingError) - } - hashValue := p.Crc32Hash.Sum32() - p.Crc32Hash.Reset() - return int64(hashValue) -} - -func (p *Plasma) Seed() uint64 { - return p.seed -} - -func (p *Plasma) LoadFeature(symbolMap Feature) { - for symbol, loader := range symbolMap { - p.BuiltInContext.PeekSymbolTable().Set(symbol, loader(p.BuiltInContext, p)) - } -} - -/* - InitializeBytecode - Loads the bytecode and clears the stack -*/ - -func (p *Plasma) StdInScanner() *bufio.Scanner { - return p.stdinScanner -} - -func (p *Plasma) StdIn() io.Reader { - return p.Stdin -} - -func (p *Plasma) StdOut() io.Writer { - return p.Stdout -} - -func (p *Plasma) StdErr() io.Writer { - return p.Stderr -} - -func (p *Plasma) BuiltInSymbols() *SymbolTable { - return p.BuiltInContext.PeekSymbolTable() -} - -func (p *Plasma) NextId() int64 { - result := p.currentId - p.currentId++ - return result -} - -func newContext() *Context { - result := &Context{ - ObjectStack: NewObjectStack(), - SymbolStack: NewSymbolStack(), - LastState: NoState, - } - return result -} - -func (p *Plasma) NewContext() *Context { - result := newContext() - symbols := NewSymbolTable(p.BuiltInContext.PeekSymbolTable()) - result.SymbolStack.Push(symbols) - - builtIn := &Value{ - id: p.NextId(), - typeName: ValueName, - class: nil, - subClasses: nil, - onDemandSymbols: map[string]OnDemandLoader{}, - IsBuiltIn: true, - symbols: p.BuiltInContext.PeekSymbolTable(), - } - p.ObjectInitialize(true)(result, builtIn) - symbols.Set("__built_in__", builtIn) - - self := &Value{ - id: p.NextId(), - typeName: ValueName, - class: nil, - onDemandSymbols: map[string]OnDemandLoader{}, - subClasses: nil, - symbols: symbols, - } - p.ObjectInitialize(true)(result, self) - symbols.Set(Self, self) - return result -} - -func NewPlasmaVM(stdin io.Reader, stdout io.Writer, stderr io.Writer) *Plasma { - number, randError := rand.Int(rand.Reader, big.NewInt(polySize)) - if randError != nil { - panic(randError) - } - vm := &Plasma{ - currentId: 1, - BuiltInContext: newContext(), - Crc32Hash: crc32.New(crc32.MakeTable(polySize)), - seed: number.Uint64(), - stdinScanner: bufio.NewScanner(stdin), - Stdin: stdin, - Stdout: stdout, - Stderr: stderr, - } - vm.BuiltInContext.PushSymbolTable(NewSymbolTable(nil)) - vm.InitializeBuiltIn() - return vm -} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/vm/proxy_object.go b/vendor/github.com/shoriwe/gplasma/pkg/vm/proxy_object.go deleted file mode 100644 index 7f3b2bc..0000000 --- a/vendor/github.com/shoriwe/gplasma/pkg/vm/proxy_object.go +++ /dev/null @@ -1,20 +0,0 @@ -package vm - -func (p *Plasma) NewProxyObject(context *Context, self, class *Value) (*Value, bool) { - symbolTable := NewSymbolTable(context.PeekSymbolTable()) - proxyObject, success := p.ConstructObject(context, class, symbolTable) - if !success { - return proxyObject, false - } - for _, value := range proxyObject.SymbolTable().Symbols { - if value.IsTypeById(FunctionId) { - switch value.Callable.(type) { - case *BuiltInClassFunction: - value.Callable.(*BuiltInClassFunction).Self = self - case *PlasmaClassFunction: - value.Callable.(*PlasmaClassFunction).Self = self - } - } - } - return proxyObject, true -} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/vm/stack.go b/vendor/github.com/shoriwe/gplasma/pkg/vm/stack.go deleted file mode 100644 index d9cdd79..0000000 --- a/vendor/github.com/shoriwe/gplasma/pkg/vm/stack.go +++ /dev/null @@ -1,77 +0,0 @@ -package vm - -type stackNode struct { - value interface{} - next *stackNode -} - -func NewStackNode(value interface{}, next *stackNode) *stackNode { - return &stackNode{ - value: value, - next: next, - } -} - -type ObjectStack struct { - head *stackNode -} - -func (stack *ObjectStack) Pop() *Value { - result := stack.head.value - stack.head = stack.head.next - return result.(*Value) -} - -func (stack *ObjectStack) Peek() *Value { - return stack.head.value.(*Value) -} - -func (stack *ObjectStack) Push(object *Value) { - stack.head = NewStackNode(object, stack.head) -} - -func (stack *ObjectStack) HasNext() bool { - return stack.head != nil -} - -func (stack *ObjectStack) Clear() { - stack.head = nil -} - -func NewObjectStack() *ObjectStack { - return &ObjectStack{ - head: nil, - } -} - -type SymbolStack struct { - head *stackNode -} - -func (stack *SymbolStack) Pop() *SymbolTable { - result := stack.head.value - stack.head = stack.head.next - return result.(*SymbolTable) -} - -func (stack *SymbolStack) Peek() *SymbolTable { - return stack.head.value.(*SymbolTable) -} - -func (stack *SymbolStack) Push(symbolTable *SymbolTable) { - stack.head = NewStackNode(symbolTable, stack.head) -} - -func (stack *SymbolStack) HasNext() bool { - return stack.head != nil -} - -func (stack *SymbolStack) Clear() { - stack.head = nil -} - -func NewSymbolStack() *SymbolStack { - return &SymbolStack{ - head: nil, - } -} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/vm/string.go b/vendor/github.com/shoriwe/gplasma/pkg/vm/string.go index d48279f..6d7b2a3 100644 --- a/vendor/github.com/shoriwe/gplasma/pkg/vm/string.go +++ b/vendor/github.com/shoriwe/gplasma/pkg/vm/string.go @@ -1,376 +1,240 @@ package vm import ( - "fmt" - "github.com/shoriwe/gplasma/pkg/tools" - "strconv" - "strings" + "bytes" + magic_functions "github.com/shoriwe/gplasma/pkg/common/magic-functions" ) -func (p *Plasma) NewString(context *Context, isBuiltIn bool, value string) *Value { - string_ := p.NewValue(context, isBuiltIn, StringName, nil, context.PeekSymbolTable()) - string_.BuiltInTypeId = StringId - string_.String = value - - p.StringInitialize(isBuiltIn)(context, string_) - string_.SetOnDemandSymbol(Self, - func() *Value { - return string_ - }, - ) - return string_ +func (plasma *Plasma) stringClass() *Value { + class := plasma.NewValue(plasma.rootSymbols, BuiltInClassId, plasma.class) + class.SetAny(Callback(func(argument ...*Value) (*Value, error) { + return plasma.NewString(argument[0].Contents()), nil + })) + return class } -func (p *Plasma) StringInitialize(isBuiltIn bool) ConstructorCallBack { - return func(context *Context, object *Value) *Value { - object.SetOnDemandSymbol(Length, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, arguments ...*Value) (*Value, bool) { - return p.NewInteger(context, false, int64(len(self.String))), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Contains, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - left := arguments[0] - if !left.IsTypeById(StringId) { - return p.NewInvalidTypeError(context, left.TypeName(), StringName), false - } - return p.InterpretAsBool(strings.Contains(self.String, left.String)), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Add, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - right := arguments[0] - if !right.IsTypeById(StringId) { - return p.NewInvalidTypeError(context, right.TypeName(), StringName), false - } - return p.NewString(context, false, - self.String+right.String, - ), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightAdd, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - left := arguments[0] - if !left.IsTypeById(StringId) { - return p.NewInvalidTypeError(context, left.TypeName(), StringName), false - } - return p.NewString(context, false, - left.String+self.String, - ), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Mul, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - right := arguments[0] - if !right.IsTypeById(IntegerId) { - return p.NewInvalidTypeError(context, right.TypeName(), IntegerName), false - } - return p.NewString(context, false, - tools.Repeat(self.String, right.Integer), - ), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightMul, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - left := arguments[0] - if !left.IsTypeById(IntegerId) { - return p.NewInvalidTypeError(context, left.TypeName(), IntegerName), false - } - return p.NewString(context, false, - tools.Repeat(self.String, left.Integer), - ), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Equals, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - right := arguments[0] - if !right.IsTypeById(StringId) { - return p.GetFalse(), true - } - return p.InterpretAsBool(self.String == right.String), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightEquals, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - left := arguments[0] - if !left.IsTypeById(StringId) { - return p.GetFalse(), true - } - return p.InterpretAsBool(left.String == self.String), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(NotEquals, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - right := arguments[0] - if !right.IsTypeById(StringId) { - return p.GetTrue(), true - } - return p.InterpretAsBool(self.String != right.String), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightNotEquals, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - left := arguments[0] - if !left.IsTypeById(StringId) { - return p.GetTrue(), true - } - return p.InterpretAsBool(left.String != self.String), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Hash, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - if self.GetHash() == 0 { - stringHash := p.HashString(fmt.Sprintf("%s-%s", self.String, StringName)) - self.SetHash(stringHash) - } - return p.NewInteger(context, false, self.GetHash()), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Copy, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.NewString(context, false, - self.String, - ), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Index, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - return p.StringIndex(context, self, arguments[0]) - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Iter, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.StringIterator(context, self) - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(ToInteger, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - number, parsingError := strconv.ParseInt(strings.ReplaceAll(self.String, "_", ""), 10, 64) - if parsingError != nil { - return p.NewIntegerParsingError(context), false - } - return p.NewInteger(context, false, number), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(ToFloat, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - number, parsingError := strconv.ParseFloat(strings.ReplaceAll(self.String, "_", ""), 64) - if parsingError != nil { - return p.NewFloatParsingError(context), false - } - return p.NewFloat(context, false, number), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(ToString, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.NewString(context, false, - self.String, - ), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(ToBool, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.InterpretAsBool(len(self.String) > 0), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(ToArray, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.StringToContent(context, self, ArrayId) - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(ToTuple, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.StringToContent(context, self, TupleId) - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(ToBytes, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.NewBytes(context, false, []byte(self.String)), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Lower, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.NewString(context, false, strings.ToLower(self.String)), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Upper, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.NewString(context, false, strings.ToUpper(self.String)), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Split, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - if !arguments[0].IsTypeById(StringId) { - return p.NewInvalidTypeError(context, arguments[0].GetClass(p).Name, StringName), false - } - var subStrings []*Value - for _, s := range strings.Split(self.String, arguments[0].String) { - subStrings = append(subStrings, p.NewString(context, false, s)) - } - return p.NewArray(context, false, subStrings), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Replace, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 2, - func(self *Value, arguments ...*Value) (*Value, bool) { - if !arguments[0].IsTypeById(StringId) { - return p.NewInvalidTypeError(context, arguments[0].GetClass(p).Name, StringName), false - } - if !arguments[1].IsTypeById(StringId) { - return p.NewInvalidTypeError(context, arguments[1].GetClass(p).Name, StringName), false - } - return p.NewString(context, false, strings.ReplaceAll(self.String, arguments[0].String, arguments[1].String)), true - }, - ), - ) - }, - ) - return nil - } +/* +NewString magic function: +In __in__ +Equal __equal__ +NotEqual __not_equal__ +Add __add__ +Mul __mul__ +Length __len__ +Bool __bool__ +String __string__ +Bytes __bytes__ +Array __array__ +Tuple __tuple__ +Get __get__ +Copy __copy__ +Iter __iter__ +Join join +Split split +Upper upper +Lower lower +Count count +Index Index +*/ +func (plasma *Plasma) NewString(contents []byte) *Value { + result := plasma.NewValue(plasma.rootSymbols, StringId, plasma.string) + result.SetAny(contents) + result.Set(magic_functions.In, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case StringId: + return plasma.NewBool(bytes.Contains(result.GetBytes(), argument[0].GetBytes())), nil + case IntId: + i := argument[0].GetInt64() + for _, b := range result.GetBytes() { + if int64(b) == i { + return plasma.true, nil + } + } + return plasma.false, nil + } + return plasma.false, nil + }, + )) + result.Set(magic_functions.Equal, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewBool(result.Equal(argument[0])), nil + }, + )) + result.Set(magic_functions.NotEqual, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewBool(!result.Equal(argument[0])), nil + }, + )) + result.Set(magic_functions.Add, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case StringId: + s := result.GetBytes() + otherS := argument[0].GetBytes() + newString := make([]byte, 0, len(s)+len(otherS)) + newString = append(newString, s...) + newString = append(newString, otherS...) + return plasma.NewString(newString), nil + } + return nil, NotOperable + }, + )) + result.Set(magic_functions.Mul, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case IntId: + s := result.GetBytes() + times := argument[0].GetInt64() + return plasma.NewString(bytes.Repeat(s, int(times))), nil + } + return nil, NotOperable + }, + )) + result.Set(magic_functions.Length, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewInt(int64(len(result.GetBytes()))), nil + }, + )) + result.Set(magic_functions.Bool, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewBool(len(result.GetBytes()) > 0), nil + }, + )) + result.Set(magic_functions.String, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return result, nil + }, + )) + result.Set(magic_functions.Bytes, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewBytes(result.GetBytes()), nil + }, + )) + result.Set(magic_functions.Array, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + s := result.GetBytes() + values := make([]*Value, 0, len(s)) + for _, b := range s { + values = append(values, plasma.NewInt(int64(b))) + } + return plasma.NewArray(values), nil + }, + )) + result.Set(magic_functions.Tuple, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + s := result.GetBytes() + values := make([]*Value, 0, len(s)) + for _, b := range s { + values = append(values, plasma.NewInt(int64(b))) + } + return plasma.NewTuple(values), nil + }, + )) + result.Set(magic_functions.Get, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case IntId: + s := result.GetBytes() + index := argument[0].GetInt64() + return plasma.NewInt(int64(s[index])), nil + case TupleId: + s := result.GetBytes() + values := argument[0].GetValues() + startIndex := values[0].GetInt64() + endIndex := values[1].GetInt64() + return plasma.NewString(s[startIndex:endIndex]), nil + } + return nil, NotIndexable + }, + )) + result.Set(magic_functions.Copy, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + s := result.GetBytes() + newS := make([]byte, len(s)) + copy(newS, s) + return plasma.NewString(newS), nil + }, + )) + result.Set(magic_functions.Iter, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + iter := plasma.NewValue(result.vtable, ValueId, plasma.value) + iter.SetAny(int64(0)) + iter.Set(magic_functions.HasNext, plasma.NewBuiltInFunction(iter.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewBool(iter.GetInt64() < int64(len(result.GetBytes()))), nil + }, + )) + iter.Set(magic_functions.Next, plasma.NewBuiltInFunction(iter.vtable, + func(argument ...*Value) (*Value, error) { + currentBytes := result.GetBytes() + index := iter.GetInt64() + iter.SetAny(index + 1) + if index < int64(len(currentBytes)) { + return plasma.NewString([]byte{currentBytes[index]}), nil + } + return plasma.none, nil + }, + )) + return iter, nil + }, + )) + result.Set(magic_functions.Join, plasma.NewBuiltInFunction(result.vtable, + func(argument ...*Value) (*Value, error) { + values := argument[0].Values() + valuesBytes := make([][]byte, 0, len(values)) + for _, value := range values { + valuesBytes = append(valuesBytes, []byte(value.String())) + } + return plasma.NewString(bytes.Join(valuesBytes, []byte(result.String()))), nil + }, + )) + result.Set(magic_functions.Split, plasma.NewBuiltInFunction(result.vtable, + func(argument ...*Value) (*Value, error) { + sep := argument[0].String() + splitted := bytes.Split(result.GetBytes(), []byte(sep)) + values := make([]*Value, 0, len(splitted)) + for _, b := range splitted { + values = append(values, plasma.NewBytes(b)) + } + return plasma.NewTuple(values), nil + }, + )) + result.Set(magic_functions.Upper, plasma.NewBuiltInFunction(result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewString(bytes.ToUpper(result.GetBytes())), nil + }, + )) + result.Set(magic_functions.Lower, plasma.NewBuiltInFunction(result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewString(bytes.ToLower(result.GetBytes())), nil + }, + )) + result.Set(magic_functions.Count, plasma.NewBuiltInFunction(result.vtable, + func(argument ...*Value) (*Value, error) { + sep := argument[0].String() + return plasma.NewInt(int64(bytes.Count(result.GetBytes(), []byte(sep)))), nil + }, + )) + result.Set(magic_functions.Index, plasma.NewBuiltInFunction(result.vtable, + func(argument ...*Value) (*Value, error) { + sep := argument[0].String() + return plasma.NewInt(int64(bytes.Index(result.GetBytes(), []byte(sep)))), nil + }, + )) + return result } diff --git a/vendor/github.com/shoriwe/gplasma/pkg/vm/symbol-table.go b/vendor/github.com/shoriwe/gplasma/pkg/vm/symbol-table.go new file mode 100644 index 0000000..7246969 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/vm/symbol-table.go @@ -0,0 +1,65 @@ +package vm + +import ( + "fmt" + "sync" +) + +var ( + SymbolNotFoundError = fmt.Errorf("symbol not found") +) + +type ( + Symbols struct { + mutex *sync.Mutex + values map[string]*Value + call *Symbols + Parent *Symbols + } +) + +func NewSymbols(parent *Symbols) *Symbols { + return &Symbols{ + mutex: &sync.Mutex{}, + values: map[string]*Value{}, + call: nil, + Parent: parent, + } +} + +func (symbols *Symbols) Set(name string, value *Value) { + symbols.mutex.Lock() + defer symbols.mutex.Unlock() + symbols.values[name] = value +} + +func (symbols *Symbols) Get(name string) (*Value, error) { + symbols.mutex.Lock() + defer symbols.mutex.Unlock() + var ( + value *Value + found bool + ) + value, found = symbols.values[name] + if found { + return value, nil + } + for current := symbols.Parent; current != nil; current = current.Parent { + value, found = current.values[name] + if found { + return value, nil + } + } + return nil, SymbolNotFoundError +} + +func (symbols *Symbols) Del(name string) error { + symbols.mutex.Lock() + defer symbols.mutex.Unlock() + _, found := symbols.values[name] + if !found { + return SymbolNotFoundError + } + delete(symbols.values, name) + return nil +} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/vm/symbol_table.go b/vendor/github.com/shoriwe/gplasma/pkg/vm/symbol_table.go deleted file mode 100644 index b9892ae..0000000 --- a/vendor/github.com/shoriwe/gplasma/pkg/vm/symbol_table.go +++ /dev/null @@ -1,39 +0,0 @@ -package vm - -import ( - "github.com/shoriwe/gplasma/pkg/errors" -) - -type SymbolTable struct { - Parent *SymbolTable - Symbols map[string]*Value -} - -func (symbolTable *SymbolTable) Set(s string, object *Value) { - symbolTable.Symbols[s] = object -} - -func (symbolTable *SymbolTable) GetSelf(symbol string) (*Value, *errors.Error) { - result, found := symbolTable.Symbols[symbol] - if !found { - return nil, errors.NewNameNotFoundError() - } - return result, nil -} - -func (symbolTable *SymbolTable) GetAny(symbol string) (*Value, *errors.Error) { - for source := symbolTable; source != nil; source = source.Parent { - result, found := source.Symbols[symbol] - if found { - return result, nil - } - } - return nil, errors.NewNameNotFoundError() -} - -func NewSymbolTable(parentSymbols *SymbolTable) *SymbolTable { - return &SymbolTable{ - Parent: parentSymbols, - Symbols: map[string]*Value{}, - } -} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/vm/tools.go b/vendor/github.com/shoriwe/gplasma/pkg/vm/tools.go deleted file mode 100644 index 900a97c..0000000 --- a/vendor/github.com/shoriwe/gplasma/pkg/vm/tools.go +++ /dev/null @@ -1,899 +0,0 @@ -package vm - -import ( - "github.com/shoriwe/gplasma/pkg/tools" -) - -func (p *Plasma) Repeat(context *Context, content []*Value, times int64) ([]*Value, *Value) { - copyFunctions := map[int64]*Value{} - var result []*Value - if times == 0 { - for _, object := range content { - copyObject, getError := object.Get(p, context, Copy) - if getError != nil { - copyFunctions[object.Id()] = nil - continue - } - copyFunctions[object.Id()] = copyObject - } - } - for i := int64(0); i < times; i++ { - for _, object := range content { - copyFunction := copyFunctions[object.Id()] - if copyFunction == nil { - result = append(result, object) - continue - } - objectCopy, success := p.CallFunction(context, copyFunction) - if !success { - return nil, objectCopy - } - result = append(result, objectCopy) - } - } - return result, nil -} - -func (p *Plasma) Equals(context *Context, leftHandSide *Value, rightHandSide *Value) (bool, *Value) { - equals, getError := leftHandSide.Get(p, context, Equals) - if getError != nil { - // Try with the rightHandSide - var rightEquals *Value - rightEquals, getError = rightHandSide.Get(p, context, RightEquals) - if getError != nil { - return false, getError - } - result, success := p.CallFunction(context, rightEquals, rightHandSide) - if !success { - return false, result - } - return p.QuickGetBool(context, result) - } - result, success := p.CallFunction(context, equals, rightHandSide) - if !success { - // Try with the rightHandSide - var rightEquals *Value - rightEquals, getError = rightHandSide.Get(p, context, RightEquals) - if getError != nil { - return false, getError - } - result, success = p.CallFunction(context, rightEquals, rightHandSide) - if !success { - return false, result - } - } - return p.QuickGetBool(context, result) -} - -func (p *Plasma) ContentEquals(context *Context, leftHandSide *Value, rightHandSide *Value) (*Value, bool) { - leftHandSideLength := len(leftHandSide.Content) - rightHandSideLength := len(rightHandSide.Content) - if leftHandSideLength != rightHandSideLength { - return p.GetFalse(), true - } - var rightEquals *Value - var comparisonResult *Value - var success bool - var callError *Value - var comparisonBool bool - - for i := 0; i < leftHandSideLength; i++ { - leftEquals, getError := rightHandSide.Content[i].Get(p, context, Equals) - if getError != nil { - rightEquals, getError = rightHandSide.Content[i].Get(p, context, RightEquals) - if getError != nil { - return getError, false - } - comparisonResult, success = p.CallFunction(context, rightEquals, leftHandSide.Content[i]) - } else { - comparisonResult, success = p.CallFunction(context, leftEquals, rightHandSide.Content[i]) - } - if !success { - return comparisonResult, false - } - comparisonBool, callError = p.QuickGetBool(context, comparisonResult) - if callError != nil { - return callError, false - } - if !comparisonBool { - return p.GetFalse(), true - } - } - return p.GetTrue(), true -} - -func (p *Plasma) ContentNotEquals(context *Context, leftHandSide *Value, rightHandSide *Value) (*Value, bool) { - leftHandSideLength := len(leftHandSide.Content) - rightHandSideLength := len(rightHandSide.Content) - if leftHandSideLength != rightHandSideLength { - return p.GetTrue(), true - } - var rightEquals *Value - var comparisonResult *Value - var success bool - var callError *Value - var comparisonBool bool - - for i := 0; i < leftHandSideLength; i++ { - leftEquals, getError := rightHandSide.Content[i].Get(p, context, Equals) - if getError != nil { - rightEquals, getError = rightHandSide.Content[i].Get(p, context, RightEquals) - if getError != nil { - return getError, false - } - comparisonResult, success = p.CallFunction(context, rightEquals, leftHandSide.Content[i]) - } else { - comparisonResult, success = p.CallFunction(context, leftEquals, rightHandSide.Content[i]) - } - if !success { - return comparisonResult, false - } - comparisonBool, callError = p.QuickGetBool(context, comparisonResult) - if callError != nil { - return callError, false - } - if !comparisonBool { - return p.GetTrue(), true - } - } - return p.GetFalse(), true -} - -func (p *Plasma) ContentContains(context *Context, source *Value, value *Value) (*Value, bool) { - valueRightEquals, getError := value.Get(p, context, RightEquals) - if getError != nil { - return getError, false - } - for _, tupleValue := range source.Content { - callResult, success := p.CallFunction(context, valueRightEquals, tupleValue) - if !success { - return callResult, false - } - var boolValue *Value - if callResult.IsTypeById(BoolId) { - boolValue = callResult - } else { - var boolValueToBool *Value - boolValueToBool, getError = callResult.Get(p, context, ToBool) - if getError != nil { - return getError, false - } - callResult, success = p.CallFunction(context, boolValueToBool) - if !success { - return callResult, false - } - if !callResult.IsTypeById(BoolId) { - return p.NewInvalidTypeError(context, callResult.TypeName(), BoolName), false - } - boolValue = callResult - } - if boolValue.Bool { - return p.GetTrue(), true - } - } - return p.GetFalse(), true -} - -func (p *Plasma) ContentCopy(context *Context, source *Value) (*Value, bool) { - var copiedObjects []*Value - for _, contentObject := range source.Content { - objectCopy, getError := contentObject.Get(p, context, Copy) - if getError != nil { - return getError, false - } - copiedObject, success := p.CallFunction(context, objectCopy) - if !success { - return copiedObject, false - } - copiedObjects = append(copiedObjects, copiedObject) - } - if source.BuiltInTypeId == TupleId { - return p.NewTuple(context, false, copiedObjects), true - } - return p.NewArray(context, false, copiedObjects), true -} - -func (p *Plasma) ContentIndex(context *Context, source *Value, indexObject *Value) (*Value, bool) { - if indexObject.IsTypeById(IntegerId) { - index, calcError := tools.CalcIndex(indexObject.Integer, len(source.Content)) - if calcError != nil { - return p.NewIndexOutOfRange(context, len(source.Content), indexObject.Integer), false - } - return source.Content[index], true - } else if indexObject.IsTypeById(TupleId) { - if len(indexObject.Content) != 2 { - return p.NewInvalidNumberOfArgumentsError(context, len(indexObject.Content), 2), false - } - startIndex, calcError := tools.CalcIndex(indexObject.Content[0].Integer, len(source.Content)) - if calcError != nil { - return p.NewIndexOutOfRange(context, len(source.Content), indexObject.Content[0].Integer), false - } - var targetIndex int - targetIndex, calcError = tools.CalcIndex(indexObject.Content[1].Integer, len(source.Content)) - if calcError != nil { - return p.NewIndexOutOfRange(context, len(source.Content), indexObject.Content[1].Integer), false - } - return p.NewArray(context, false, source.Content[startIndex:targetIndex]), true - } - return p.NewInvalidTypeError(context, indexObject.TypeName(), IntegerName, TupleName), false -} - -func (p *Plasma) ContentToString(context *Context, source *Value) (*Value, bool) { - var opening string - var closing string - switch source.BuiltInTypeId { - case ArrayId: - opening = "[" - closing = "]" - case TupleId: - opening = "(" - closing = ")" - } - var objectString *Value - var success bool - result := "" - for index, contentObject := range source.Content { - if index != 0 { - result += ", " - } - objectToString, getError := contentObject.Get(p, context, ToString) - if getError != nil { - return getError, false - } - objectString, success = p.CallFunction(context, objectToString) - if !success { - return objectString, false - } - result += objectString.String - } - return p.NewString(context, false, opening+result+closing), true -} - -func (p *Plasma) ContentAssign(context *Context, source, indexObject *Value, value *Value) (*Value, bool) { - if !indexObject.IsTypeById(IntegerId) { - return p.NewInvalidTypeError(context, indexObject.GetClass(p).Name, IntegerName), false - } - index, calcError := tools.CalcIndex(indexObject.Integer, len(source.Content)) - if calcError != nil { - return p.NewIndexOutOfRange(context, len(source.Content), indexObject.Integer), false - } - source.Content[index] = value - return p.GetNone(), true -} - -func (p *Plasma) ContentIterator(context *Context, source *Value) (*Value, bool) { - result := p.NewIterator(context, false) - information := struct { - index int - length int - }{ - 0, - len(source.Content), - } - result.Set( - p, context, - Next, - p.NewFunction( - context, - false, - context.PeekSymbolTable(), - NewBuiltInClassFunction( - result, - 0, - func(self *Value, _ ...*Value) (*Value, bool) { - if information.index >= information.length { - return p.NewIndexOutOfRange(context, information.length, int64(information.index)), false - } - r := source.Content[information.index] - information.index++ - return r, true - }, - ), - ), - ) - result.Set( - p, context, - HasNext, - p.NewFunction( - context, - false, - context.PeekSymbolTable(), - NewBuiltInClassFunction( - result, - 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.InterpretAsBool(information.index < information.length), true - }, - ), - ), - ) - return result, true -} - -func (p *Plasma) BytesIterator(context *Context, source *Value) (*Value, bool) { - result := p.NewIterator(context, false) - information := struct { - index int - length int - }{ - 0, - len(source.Bytes), - } - result.Set( - p, context, - Next, - p.NewFunction( - context, - false, - context.PeekSymbolTable(), - NewBuiltInClassFunction( - result, - 0, - func(self *Value, _ ...*Value) (*Value, bool) { - if information.index >= information.length { - return p.NewIndexOutOfRange(context, information.length, int64(information.index)), false - } - r := self.Bytes[information.index] - information.index++ - return p.NewInteger(context, false, int64(r)), true - }, - ), - ), - ) - result.Set( - p, context, - HasNext, - p.NewFunction( - context, - false, - context.PeekSymbolTable(), - NewBuiltInClassFunction( - result, - 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.InterpretAsBool(information.index < information.length), true - }, - ), - ), - ) - return result, true -} - -func (p *Plasma) StringIterator(context *Context, source *Value) (*Value, bool) { - result := p.NewIterator(context, false) - asRune := []rune(source.String) - information := struct { - index int - length int - }{ - 0, - len(asRune), - } - result.Set( - p, context, - Next, - p.NewFunction( - context, - false, - context.PeekSymbolTable(), - NewBuiltInClassFunction( - result, - 0, - func(self *Value, _ ...*Value) (*Value, bool) { - if information.index >= information.length { - return p.NewIndexOutOfRange(context, information.length, int64(information.index)), false - } - r := asRune[information.index] - information.index++ - return p.NewString(context, false, string(r)), true - }, - ), - ), - ) - result.Set( - p, context, - HasNext, - p.NewFunction( - context, - false, - context.PeekSymbolTable(), - NewBuiltInClassFunction( - result, - 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.InterpretAsBool(information.index < information.length), true - }, - ), - ), - ) - return result, true -} - -func (p *Plasma) InterpretAsBool(expression bool) *Value { - if expression { - return p.GetTrue() - } - return p.GetFalse() -} - -func (p *Plasma) StringIndex(context *Context, source *Value, indexObject *Value) (*Value, bool) { - if indexObject.IsTypeById(IntegerId) { - index, getIndexError := tools.CalcIndex(indexObject.Integer, len(source.String)) - if getIndexError != nil { - return p.NewIndexOutOfRange(context, len(source.String), indexObject.Integer), false - } - return p.NewString(context, false, string(source.String[index])), true - } else if indexObject.IsTypeById(TupleId) { - if len(indexObject.Content) != 2 { - return p.NewInvalidNumberOfArgumentsError(context, len(indexObject.Content), 2), false - } - startIndex, calcError := tools.CalcIndex(indexObject.Content[0].Integer, len(source.String)) - if calcError != nil { - return p.NewIndexOutOfRange(context, len(source.String), indexObject.Content[0].Integer), false - } - var targetIndex int - targetIndex, calcError = tools.CalcIndex(indexObject.Content[1].Integer, len(source.String)) - if calcError != nil { - return p.NewIndexOutOfRange(context, len(source.String), indexObject.Content[1].Integer), false - } - return p.NewString(context, false, source.String[startIndex:targetIndex]), true - } - return p.NewInvalidTypeError(context, indexObject.TypeName(), IntegerName, TupleName), false -} - -func (p *Plasma) BytesIndex(context *Context, source *Value, indexObject *Value) (*Value, bool) { - if indexObject.IsTypeById(IntegerId) { - index, calcError := tools.CalcIndex(indexObject.Integer, len(source.Bytes)) - if calcError != nil { - return p.NewIndexOutOfRange(context, len(source.Bytes), indexObject.Integer), false - } - return p.NewInteger(context, false, int64(source.Bytes[index])), true - } else if indexObject.IsTypeById(TupleId) { - if len(indexObject.Content) != 2 { - return p.NewInvalidNumberOfArgumentsError(context, len(indexObject.Content), 2), false - } - startIndex, calcError := tools.CalcIndex(indexObject.Content[0].Integer, len(source.Bytes)) - if calcError != nil { - return p.NewIndexOutOfRange(context, len(source.Bytes), indexObject.Content[0].Integer), false - } - var targetIndex int - targetIndex, calcError = tools.CalcIndex(indexObject.Content[1].Integer, len(source.Bytes)) - if calcError != nil { - return p.NewIndexOutOfRange(context, len(source.Bytes), indexObject.Content[1].Integer), false - } - return p.NewBytes(context, false, source.Bytes[startIndex:targetIndex]), true - } - return p.NewInvalidTypeError(context, indexObject.TypeName(), IntegerName, TupleName), false -} - -func (p *Plasma) Hash(context *Context, value *Value) (*Value, bool) { - objectHashFunc, getError := value.Get(p, context, Hash) - if getError != nil { - return getError, false - } - objectHash, success := p.CallFunction(context, objectHashFunc) - if !success { - return objectHash, false - } - if !objectHash.IsTypeById(IntegerId) { - return p.NewInvalidTypeError(context, objectHash.TypeName(), IntegerName), false - } - return objectHash, true -} - -func (p *Plasma) HashIndexAssign(context *Context, hash *Value, key *Value, value *Value) (*Value, bool) { - indexHash, success := p.Hash(context, key) - if !success { - return indexHash, false - } - if !indexHash.IsTypeById(IntegerId) { - return p.NewInvalidTypeError(context, indexHash.TypeName(), IntegerName), false - } - keyValues, found := hash.KeyValues[indexHash.Integer] - if found { - hash.AddKeyValue(indexHash.Integer, &KeyValue{ - Key: key, - Value: value, - }) - return p.GetNone(), true - } - indexObjectEquals, getError := key.Get(p, context, Equals) - if getError != nil { - return getError, false - } - var equals *Value - for index, keyValue := range keyValues { - equals, success = p.CallFunction(context, indexObjectEquals, keyValue.Key) - if !success { - return equals, false - } - equalsBool, callError := p.QuickGetBool(context, equals) - if callError != nil { - return callError, false - } - if equalsBool { - hash.KeyValues[indexHash.Integer][index].Value = value - return p.GetNone(), true - } - } - hash.KeyValues[indexHash.Integer] = append( - hash.KeyValues[indexHash.Integer], - &KeyValue{ - Key: key, - Value: value, - }, - ) - return p.GetNone(), true -} - -func (p *Plasma) HashEquals(context *Context, leftHandSide *Value, rightHandSide *Value) (*Value, bool) { - if !leftHandSide.IsTypeById(HashTableId) && !rightHandSide.IsTypeById(HashTableId) { - return p.NewInvalidTypeError(context, leftHandSide.Name, HashName), false - } else if !leftHandSide.IsTypeById(HashTableId) { - return p.GetFalse(), true - } else if !rightHandSide.IsTypeById(HashTableId) { - return p.GetFalse(), true - } - rightIndex, getError := rightHandSide.Get(p, context, Index) - if getError != nil { - return getError, false - } - for key, leftValue := range leftHandSide.KeyValues { - // Check if other has the key - rightValue, ok := rightHandSide.KeyValues[key] - if !ok { - return p.GetFalse(), true - } - // Check if the each entry one has the same length - if len(leftValue) != len(rightValue) { - return p.GetFalse(), true - } - // Start comparing the entries - for _, entry := range leftValue { - _, success := p.CallFunction(context, rightIndex, entry.Key) - if !success { - return p.GetFalse(), true - } - } - } - return p.GetTrue(), true -} - -func (p *Plasma) HashNotEquals(context *Context, leftHandSide *Value, rightHandSide *Value) (*Value, bool) { - if !leftHandSide.IsTypeById(HashTableId) && !rightHandSide.IsTypeById(HashTableId) { - return p.NewInvalidTypeError(context, leftHandSide.Name, HashName), false - } else if !leftHandSide.IsTypeById(HashTableId) { - return p.GetTrue(), true - } else if !rightHandSide.IsTypeById(HashTableId) { - return p.GetTrue(), true - } - - rightIndex, getError := rightHandSide.Get(p, context, Index) - if getError != nil { - return getError, false - } - for key, leftValue := range leftHandSide.KeyValues { - // Check if other has the key - rightValue, ok := rightHandSide.KeyValues[key] - if !ok { - return p.GetTrue(), true - } - // Check if the each entry one has the same length - if len(leftValue) != len(rightValue) { - return p.GetTrue(), true - } - // Start comparing the entries - for _, entry := range leftValue { - _, success := p.CallFunction(context, rightIndex, entry.Key) - if !success { - return p.GetTrue(), true - } - } - } - return p.GetFalse(), true -} - -func (p *Plasma) HashContent(context *Context, value *Value) (*Value, bool) { - tupleHash := XXPrime5 ^ p.Seed() - for _, contentObject := range value.Content { - objectHash, success := p.Hash(context, contentObject) - if !success { - return objectHash, false - } - tupleHash += uint64(objectHash.Integer) * XXPrime2 - tupleHash = (tupleHash << 31) | (tupleHash >> 33) - tupleHash *= XXPrime1 - tupleHash &= (1 << 64) - 1 - } - return p.NewInteger(context, false, int64(tupleHash)), true -} - -func (p *Plasma) HashToContent(context *Context, source *Value, target uint8) (*Value, bool) { - var keys []*Value - for _, keyValues := range source.KeyValues { - for _, keyValue := range keyValues { - keys = append(keys, keyValue.Key) - } - } - switch target { - case ArrayId: - return p.NewArray(context, false, keys), true - case TupleId: - return p.NewTuple(context, false, keys), true - } - return p.NewInvalidTypeError(context, "UNKNOWN", HashName), false -} - -func (p *Plasma) HashIterator(context *Context, source *Value) (*Value, bool) { - tuple, success := p.HashToContent(context, source, TupleId) - if !success { - return tuple, false - } - information := struct { - index int - length int - }{ - 0, - len(tuple.Content), - } - result := p.NewIterator(context, false) - result.Set( - p, context, - Next, - p.NewFunction( - context, - false, - context.PeekSymbolTable(), - NewBuiltInClassFunction( - result, - 0, - func(self *Value, _ ...*Value) (*Value, bool) { - if information.index >= information.length { - return p.NewIndexOutOfRange(context, information.length, int64(information.index)), false - } - r := tuple.Content[information.index] - information.index++ - return r, true - }, - ), - ), - ) - result.Set( - p, context, - HasNext, - p.NewFunction( - context, - false, - context.PeekSymbolTable(), - NewBuiltInClassFunction( - result, - 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.InterpretAsBool(information.index < information.length), true - }, - ), - ), - ) - return result, true -} - -func (p *Plasma) HashIndex(context *Context, source *Value, indexObject *Value) (*Value, bool) { - indexObjectHash, getError := indexObject.Get(p, context, Hash) - if getError != nil { - return getError, false - } - indexHash, success := p.CallFunction(context, indexObjectHash) - if !success { - return indexHash, false - } - if !indexHash.IsTypeById(IntegerId) { - return p.NewInvalidTypeError(context, indexHash.TypeName(), IntegerName), false - } - keyValues, found := source.KeyValues[indexHash.Integer] - if !found { - return p.NewKeyNotFoundError(context, indexObject), false - } - var indexObjectEquals *Value - indexObjectEquals, getError = indexObject.Get(p, context, Equals) - if getError != nil { - return getError, false - } - var equals *Value - for _, keyValue := range keyValues { - equals, success = p.CallFunction(context, indexObjectEquals, keyValue.Key) - if !success { - return equals, false - } - equalsBool, callError := p.QuickGetBool(context, equals) - if callError != nil { - return callError, false - } - if equalsBool { - return keyValue.Value, true - } - } - return p.NewKeyNotFoundError(context, indexObject), false -} - -func (p *Plasma) HashContains(context *Context, source *Value, value *Value) (*Value, bool) { - valueHashFunc, getError := value.Get(p, context, Hash) - if getError != nil { - return getError, false - } - valueHashObject, success := p.CallFunction(context, valueHashFunc) - if !success { - return valueHashObject, false - } - if !valueHashObject.IsTypeById(IntegerId) { - return p.NewInvalidTypeError(context, valueHashObject.TypeName(), IntegerName), false - } - valueHash := valueHashObject.Integer - entries, found := source.KeyValues[valueHash] - if !found { - return p.GetFalse(), true - } - var valueEquals *Value - valueEquals, getError = value.Get(p, context, RightEquals) - if getError != nil { - return getError, false - } - var comparisonResult *Value - for _, entry := range entries { - comparisonResult, success = p.CallFunction(context, valueEquals, entry.Key) - if !success { - return comparisonResult, false - } - comparisonResultBool, callError := p.QuickGetBool(context, comparisonResult) - if callError != nil { - return callError, false - } - if comparisonResultBool { - return p.GetTrue(), true - } - } - return p.GetFalse(), true -} - -func (p *Plasma) IndexCall(context *Context, source *Value, index *Value) (*Value, bool) { - indexOperation, getError := source.Get(p, context, Index) - if getError != nil { - return getError, false - } - return p.CallFunction(context, indexOperation, index) -} - -func (p *Plasma) StringToContent(context *Context, s *Value, target uint8) (*Value, bool) { - var content []*Value - for _, char := range []rune(s.String) { - content = append(content, p.NewString(context, false, string(char))) - } - if target == ArrayId { - return p.NewArray(context, false, content), true - } else if target == TupleId { - return p.NewTuple(context, false, content), true - } - panic("String to content only support ArrayId and TupleId") -} - -func (p *Plasma) InterpretAsIterator(context *Context, value *Value) (*Value, bool) { - _, foundNext := value.Get(p, context, Next) - _, foundHasNext := value.Get(p, context, HasNext) - if foundNext == nil && foundHasNext == nil { - return value, true - } - iter, getError := value.Get(p, context, Iter) - if getError != nil { - return getError, false - } - asIter, success := p.CallFunction(context, iter) - if !success { - return asIter, false - } - return asIter, true -} - -func (p *Plasma) BytesToContent(context *Context, s *Value, target uint8) (*Value, bool) { - var newContent []*Value - for _, byte_ := range s.Bytes { - newContent = append(newContent, - p.NewInteger(context, false, - int64(byte_), - ), - ) - } - if target == ArrayId { - return p.NewArray(context, false, newContent), true - } else if target == TupleId { - return p.NewTuple(context, false, newContent), true - } - panic("Bytes to content only support ArrayId and TupleId") -} - -func (p *Plasma) IterToContent(context *Context, s *Value, target uint8) (*Value, bool) { - next, nextGetError := s.Get(p, context, Next) - if nextGetError != nil { - return nextGetError, false - } - hasNext, hasNextGetError := s.Get(p, context, HasNext) - if hasNextGetError != nil { - return hasNextGetError, false - } - var content []*Value - for { - doesHasNext, success := p.CallFunction(context, hasNext) - if !success { - return doesHasNext, false - } - doesHasNextAsBool, interpretationError := p.QuickGetBool(context, doesHasNext) - if interpretationError != nil { - return interpretationError, false - } - if !doesHasNextAsBool { - break - } - var nextValue *Value - nextValue, success = p.CallFunction(context, next) - if !success { - return nextValue, false - } - content = append(content, nextValue) - } - if target == ArrayId { - return p.NewArray(context, false, content), true - } else if target == TupleId { - return p.NewTuple(context, false, content), true - } - panic("Iter to content only support ArrayId and TupleId") -} - -func (p *Plasma) UnpackValues(context *Context, source *Value, numberOfReceivers int) ([]*Value, *Value) { - if numberOfReceivers <= 1 { - return []*Value{source}, nil - } - switch source.BuiltInTypeId { - case TupleId, ArrayId: - return source.Content, nil - case HashTableId: - hashAsTuple, success := p.HashToContent(context, source, TupleId) - if !success { - return nil, hashAsTuple - } - return hashAsTuple.Content, nil - case StringId: - stringAsTuple, success := p.StringToContent(context, source, TupleId) - if !success { - return nil, stringAsTuple - } - return stringAsTuple.Content, nil - case BytesId: - bytesAsTuple, success := p.BytesToContent(context, source, TupleId) - if !success { - return nil, bytesAsTuple - } - return bytesAsTuple.Content, nil - case IteratorId: - iterAsTuple, success := p.IterToContent(context, source, TupleId) - if !success { - return nil, iterAsTuple - } - return iterAsTuple.Content, nil - } - // Transform the type to iter - asIterInterpretation, success := p.InterpretAsIterator(context, source) - if !success { - return nil, asIterInterpretation - } - var sourceAsIter *Value - sourceAsIter, success = p.CallFunction(context, asIterInterpretation) - if !success { - return nil, sourceAsIter - } - // The to Tuple - var sourceIterAsTuple *Value - sourceIterAsTuple, success = p.IterToContent(context, sourceAsIter, TupleId) - if !success { - return nil, sourceIterAsTuple - } - // Return its content - return sourceIterAsTuple.Content, nil -} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/vm/tuple.go b/vendor/github.com/shoriwe/gplasma/pkg/vm/tuple.go index 43b18a4..9d164c8 100644 --- a/vendor/github.com/shoriwe/gplasma/pkg/vm/tuple.go +++ b/vendor/github.com/shoriwe/gplasma/pkg/vm/tuple.go @@ -1,216 +1,154 @@ package vm -func (p *Plasma) NewTuple(context *Context, isBuiltIn bool, content []*Value) *Value { - tuple := p.NewValue(context, isBuiltIn, TupleName, nil, context.PeekSymbolTable()) - tuple.BuiltInTypeId = TupleId - tuple.Content = content - p.TupleInitialize(isBuiltIn)(context, tuple) - tuple.SetOnDemandSymbol(Self, - func() *Value { - return tuple - }, - ) - return tuple +import ( + magic_functions "github.com/shoriwe/gplasma/pkg/common/magic-functions" +) + +func (plasma *Plasma) tupleClass() *Value { + class := plasma.NewValue(plasma.rootSymbols, BuiltInClassId, plasma.class) + class.SetAny(Callback(func(argument ...*Value) (*Value, error) { + return plasma.NewTuple(argument[0].Values()), nil + })) + return class } -func (p *Plasma) TupleInitialize(isBuiltIn bool) ConstructorCallBack { - return func(context *Context, object *Value) *Value { - object.SetOnDemandSymbol(Length, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, arguments ...*Value) (*Value, bool) { - return p.NewInteger(context, false, int64(len(self.Content))), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Mul, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - right := arguments[0] - switch right.BuiltInTypeId { - case IntegerId: - content, repetitionError := p.Repeat(context, self.Content, right.Integer) - if repetitionError != nil { - return repetitionError, false - } - return p.NewTuple(context, false, content), true - default: - return p.NewInvalidTypeError(context, right.TypeName(), IntegerName, FloatName, StringName, ArrayName, TupleName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightMul, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - left := arguments[0] - switch left.BuiltInTypeId { - case IntegerId: - content, repetitionError := p.Repeat(context, self.Content, left.Integer) - if repetitionError != nil { - return repetitionError, false - } - return p.NewTuple(context, false, content), true - default: - return p.NewInvalidTypeError(context, left.TypeName(), IntegerName, FloatName, StringName, ArrayName, TupleName), false - } - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Equals, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - return p.ContentEquals(context, self, arguments[0]) - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightEquals, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - return p.ContentEquals(context, arguments[0], self) - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(NotEquals, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - return p.ContentNotEquals(context, self, arguments[0]) - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightNotEquals, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - return p.ContentNotEquals(context, arguments[0], self) - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Contains, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - return p.ContentContains(context, self, arguments[0]) - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Hash, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.HashContent(context, self) - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Copy, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.ContentCopy(context, self) - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Index, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - return p.ContentIndex(context, self, arguments[0]) - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Iter, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.ContentIterator(context, self) - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(ToString, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.ContentToString(context, self) - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(ToBool, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.InterpretAsBool(len(self.Content) != 0), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(ToArray, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.NewArray(context, false, append([]*Value{}, self.Content...)), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(ToTuple, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.NewTuple(context, false, append([]*Value{}, self.Content...)), true - }, - ), - ) - }, - ) - return nil - } +/* +NewTuple magic function: +In __in__ +Equal __equal__ +NotEqual __not_equal__ +Mul __mul__ +Length __len__ +Bool __bool__ +String __string__ +Bytes __bytes__ +Array __array__ +Tuple __tuple__ +Get __get__ +Copy __copy__ +Iter __iter__ +*/ +func (plasma *Plasma) NewTuple(values []*Value) *Value { + result := plasma.NewValue(plasma.rootSymbols, TupleId, plasma.tuple) + result.SetAny(values) + result.Set(magic_functions.In, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + for _, value := range result.GetValues() { + if value.Equal(argument[0]) { + return plasma.true, nil + } + } + return plasma.false, nil + })) + result.Set(magic_functions.Equal, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case ArrayId: + otherValues := argument[0].GetValues() + for index, value := range result.GetValues() { + if !value.Equal(otherValues[index]) { + return plasma.false, nil + } + } + } + return plasma.true, nil + })) + result.Set(magic_functions.NotEqual, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case ArrayId: + otherValues := argument[0].GetValues() + for index, value := range result.GetValues() { + if value.Equal(otherValues[index]) { + return plasma.false, nil + } + } + } + return plasma.true, nil + })) + result.Set(magic_functions.Length, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewInt(int64(len(result.GetValues()))), nil + })) + result.Set(magic_functions.Bool, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewBool(len(result.GetValues()) > 0), nil + })) + result.Set(magic_functions.String, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + var rawString []byte + rawString = append(rawString, '(') + for index, value := range result.GetValues() { + if index != 0 { + rawString = append(rawString, ',', ' ') + } + rawString = append(rawString, value.String()...) + } + rawString = append(rawString, ')') + return plasma.NewString(rawString), nil + })) + result.Set(magic_functions.Bytes, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + var rawString []byte + rawString = append(rawString, '[') + for index, value := range result.GetValues() { + if index != 0 { + rawString = append(rawString, ',', ' ') + } + rawString = append(rawString, value.String()...) + } + rawString = append(rawString, ']') + return plasma.NewBytes(rawString), nil + })) + result.Set(magic_functions.Array, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewArray(result.GetValues()), nil + })) + result.Set(magic_functions.Tuple, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + return result, nil + })) + result.Set(magic_functions.Get, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + switch argument[0].TypeId() { + case IntId: + return result.GetValues()[argument[0].GetInt64()], nil + default: + return nil, NotIndexable + } + })) + result.Set(magic_functions.Iter, plasma.NewBuiltInFunction( + result.vtable, + func(argument ...*Value) (*Value, error) { + iter := plasma.NewValue(result.vtable, ValueId, plasma.value) + iter.SetAny(int64(0)) + iter.Set(magic_functions.HasNext, plasma.NewBuiltInFunction(iter.vtable, + func(argument ...*Value) (*Value, error) { + return plasma.NewBool(iter.GetInt64() < int64(len(result.GetValues()))), nil + }, + )) + iter.Set(magic_functions.Next, plasma.NewBuiltInFunction(iter.vtable, + func(argument ...*Value) (*Value, error) { + currentValues := result.GetValues() + index := iter.GetInt64() + iter.SetAny(index + 1) + if index < int64(len(currentValues)) { + return currentValues[index], nil + } + return plasma.none, nil + }, + )) + return iter, nil + })) + return result } diff --git a/vendor/github.com/shoriwe/gplasma/pkg/vm/type.go b/vendor/github.com/shoriwe/gplasma/pkg/vm/type.go deleted file mode 100644 index ba71046..0000000 --- a/vendor/github.com/shoriwe/gplasma/pkg/vm/type.go +++ /dev/null @@ -1,32 +0,0 @@ -package vm - -func (p *Plasma) NewType( - context *Context, - isBuiltIn bool, - typeName string, - parent *SymbolTable, - subclasses []*Value, - constructor Constructor, -) *Value { - result := p.NewValue(context, isBuiltIn, TypeName, subclasses, parent) - result.BuiltInTypeId = TypeId - result.Constructor = constructor - result.Name = typeName - result.SetOnDemandSymbol(ToString, - func() *Value { - return p.NewFunction(context, isBuiltIn, result.symbols, - NewBuiltInClassFunction(result, 0, - func(_ *Value, _ ...*Value) (*Value, bool) { - return p.NewString(context, false, "Type@"+typeName), true - }, - ), - ) - }, - ) - result.SetOnDemandSymbol(Self, - func() *Value { - return result - }, - ) - return result -} diff --git a/vendor/github.com/shoriwe/gplasma/pkg/vm/type_names.go b/vendor/github.com/shoriwe/gplasma/pkg/vm/type_names.go deleted file mode 100644 index 1e18a43..0000000 --- a/vendor/github.com/shoriwe/gplasma/pkg/vm/type_names.go +++ /dev/null @@ -1,26 +0,0 @@ -package vm - -const ( - TypeName = "Type" - ValueName = "Value" - FunctionName = "Function" - StringName = "String" - BoolName = "Bool" - TrueName = "True" - FalseName = "False" - TupleName = "Tuple" - IntegerName = "Integer" - FloatName = "Float" - ArrayName = "Array" - NoneName = "NoneType" - BytesName = "Bytes" - HashName = "Hash" - IteratorName = "Iterator" - ModuleName = "Module" - None = "None" - CallableName = "Callable" - Source = "0xFFFFFF" - TemporalVariable1 = "0xAAAAAA" - TemporalVariable2 = "0xBBBBBB" - JunkVariable = "0N-JUNK-VARIABLE" -) diff --git a/vendor/github.com/shoriwe/gplasma/pkg/vm/value.go b/vendor/github.com/shoriwe/gplasma/pkg/vm/value.go index cafd3c1..199082b 100644 --- a/vendor/github.com/shoriwe/gplasma/pkg/vm/value.go +++ b/vendor/github.com/shoriwe/gplasma/pkg/vm/value.go @@ -1,627 +1,534 @@ package vm import ( + "bytes" "fmt" + "github.com/shoriwe/gplasma/pkg/lexer" + "sync" ) -type OnDemandLoader func() *Value - const ( - ValueId = iota - HashTableId - IteratorId - BoolId - FunctionId - IntegerId - FloatId + ValueId TypeId = iota StringId BytesId + BoolId + NoneId + IntId + FloatId ArrayId TupleId - ModuleId - TypeId - NoneId + HashId + BuiltInFunctionId + FunctionId + BuiltInClassId + ClassId ) -type Value struct { - IsBuiltIn bool - id int64 - typeName string - BuiltInTypeId uint16 - class *Value - subClasses []*Value - symbols *SymbolTable - Callable Callable - Constructor Constructor - Name string - hash int64 - Bool bool - String string - Bytes []uint8 - Integer int64 - Float float64 - Content []*Value - KeyValues map[int64][]*KeyValue - onDemandSymbols map[string]OnDemandLoader -} - -func (o *Value) AddKeyValue(hash int64, keyValue *KeyValue) { - o.KeyValues[hash] = append(o.KeyValues[hash], keyValue) -} - -func (o *Value) Id() int64 { - return o.id -} - -func (o *Value) SubClasses() []*Value { - return o.subClasses -} - -func (o *Value) Get(p *Plasma, context *Context, symbol string) (*Value, *Value) { - result, getError := o.symbols.GetSelf(symbol) - if getError != nil { - loader, found := o.onDemandSymbols[symbol] - if !found { - return nil, p.NewObjectWithNameNotFoundError(context, o.GetClass(p), symbol) - } - result = loader() - o.Set(p, context, symbol, result) +type ( + TypeId int + Callback func(argument ...*Value) (*Value, error) + FuncInfo struct { + Arguments []string + Bytecode []byte + } + ClassInfo struct { + prepared bool + Bases []*Value + Bytecode []byte + } + Value struct { + onDemand map[string]func(self *Value) *Value + class *Value + typeId TypeId + mutex *sync.Mutex + v any + vtable *Symbols + } +) + +func (plasma *Plasma) valueClass() *Value { + class := plasma.NewValue(plasma.rootSymbols, BuiltInClassId, plasma.class) + class.SetAny(Callback(func(argument ...*Value) (*Value, error) { + return plasma.NewValue(plasma.rootSymbols, ValueId, plasma.value), nil + })) + return class +} + +func (value *Value) GetClass() *Value { + value.mutex.Lock() + defer value.mutex.Unlock() + return value.class +} + +func (value *Value) TypeId() TypeId { + value.mutex.Lock() + defer value.mutex.Unlock() + return value.typeId +} + +func (value *Value) VirtualTable() *Symbols { + value.mutex.Lock() + defer value.mutex.Unlock() + return value.vtable +} + +func (value *Value) SetAny(v any) { + value.mutex.Lock() + defer value.mutex.Unlock() + value.v = v +} + +func (value *Value) GetHash() *Hash { + value.mutex.Lock() + defer value.mutex.Unlock() + return value.v.(*Hash) +} + +func (value *Value) GetCallback() Callback { + value.mutex.Lock() + defer value.mutex.Unlock() + return value.v.(Callback) +} + +func (value *Value) GetValues() []*Value { + value.mutex.Lock() + defer value.mutex.Unlock() + return value.v.([]*Value) +} + +func (value *Value) GetFuncInfo() FuncInfo { + value.mutex.Lock() + defer value.mutex.Unlock() + return value.v.(FuncInfo) +} + +func (value *Value) GetClassInfo() *ClassInfo { + value.mutex.Lock() + defer value.mutex.Unlock() + return value.v.(*ClassInfo) +} + +func (value *Value) GetBytes() []byte { + value.mutex.Lock() + defer value.mutex.Unlock() + return value.v.([]byte) +} + +func (value *Value) GetBool() bool { + value.mutex.Lock() + defer value.mutex.Unlock() + return value.v.(bool) +} + +func (value *Value) GetInt64() int64 { + value.mutex.Lock() + defer value.mutex.Unlock() + return value.v.(int64) +} + +func (value *Value) GetFloat64() float64 { + value.mutex.Lock() + defer value.mutex.Unlock() + return value.v.(float64) +} + +func (value *Value) GetAny() any { + value.mutex.Lock() + defer value.mutex.Unlock() + return value.v +} + +func (value *Value) Set(symbol string, v *Value) { + value.vtable.Set(symbol, v) +} + +func (value *Value) Get(symbol string) (*Value, error) { + result, getError := value.vtable.Get(symbol) + if getError == nil { + return result, nil + } + value.mutex.Lock() + defer value.mutex.Unlock() + onDemand, found := value.onDemand[symbol] + if !found { + return nil, SymbolNotFoundError } + result = onDemand(value) + value.vtable.Set(symbol, result) return result, nil } -func (o *Value) SetOnDemandSymbol(symbol string, loader OnDemandLoader) { - o.onDemandSymbols[symbol] = loader +func (value *Value) Del(symbol string) error { + return value.vtable.Del(symbol) } -func (o *Value) GetOnDemandSymbolLoader(symbol string) OnDemandLoader { - return o.onDemandSymbols[symbol] +func (value *Value) Bool() bool { + switch value.TypeId() { + case ValueId: + return true + case StringId, BytesId: + return len(value.GetBytes()) > 0 + case BoolId: + return value.GetBool() + case NoneId: + return false + case IntId: + return value.GetInt64() != 0 + case FloatId: + return value.GetFloat64() != 0 + case ArrayId, TupleId: + return len(value.GetValues()) > 0 + case HashId: + return value.GetHash().Size() > 0 + case BuiltInFunctionId: + return true + case FunctionId: + return true + case BuiltInClassId: + return true + case ClassId: + return true + } + return false +} + +func (value *Value) String() string { + switch value.TypeId() { + case ValueId: + return "?Value" + case StringId, BytesId: + return string(value.GetBytes()) + case BoolId: + if value.GetBool() { + return lexer.TrueString + } + return lexer.FalseString + case NoneId: + return lexer.NoneString + case IntId: + return fmt.Sprintf("%d", value.GetInt64()) + case FloatId: + return fmt.Sprintf("%f", value.GetFloat64()) + case ArrayId: + return "[...]" + case TupleId: + return "(...)" + case HashId: + return "{...}" + case BuiltInFunctionId: + return "?BuiltInFunction" + case FunctionId: + return "?Function" + case BuiltInClassId: + return "?BuiltInClass" + case ClassId: + return "?Class" + } + return "" } -func (o *Value) GetOnDemandSymbols() map[string]OnDemandLoader { - return o.onDemandSymbols + +func (value *Value) Contents() []byte { + switch value.TypeId() { + case ValueId: + return nil + case StringId, BytesId: + return value.GetBytes() + case BoolId: + return nil + case NoneId: + return nil + case IntId: + return nil + case FloatId: + return nil + case ArrayId: + return nil + case TupleId: + return nil + case HashId: + return nil + case BuiltInFunctionId: + return nil + case FunctionId: + return nil + case BuiltInClassId: + return nil + case ClassId: + return nil + } + return nil } -func (o *Value) Dir() map[string]byte { - result := map[string]byte{} - for symbol := range o.symbols.Symbols { - result[symbol] = 0 +func (value *Value) Int() int64 { + switch value.TypeId() { + case ValueId: + return 0 + case StringId: + return 0 + case BytesId: + return 0 + case BoolId: + if value.GetBool() { + return 1 + } + return 0 + case NoneId: + return 0 + case IntId: + return value.GetInt64() + case FloatId: + return int64(value.GetFloat64()) + case ArrayId: + return 0 + case TupleId: + return 0 + case HashId: + return 0 + case BuiltInFunctionId: + return 0 + case FunctionId: + return 0 + case BuiltInClassId: + return 0 + case ClassId: + return 0 } - for symbol := range o.onDemandSymbols { - result[symbol] = 0 + return 0 +} + +func (value *Value) Float() float64 { + switch value.TypeId() { + case ValueId: + return 0 + case StringId: + return 0 + case BytesId: + return 0 + case BoolId: + if value.GetBool() { + return 1 + } + return 0 + case NoneId: + return 0 + case IntId: + return float64(value.GetInt64()) + case FloatId: + return value.GetFloat64() + case ArrayId: + return 0 + case TupleId: + return 0 + case HashId: + return 0 + case BuiltInFunctionId: + return 0 + case FunctionId: + return 0 + case BuiltInClassId: + return 0 + case ClassId: + return 0 } - return result + return 0 } -func (o *Value) Set(p *Plasma, context *Context, symbol string, object *Value) *Value { - if o.IsBuiltIn { - return p.NewBuiltInSymbolProtectionError(context, symbol) +func (value *Value) Values() []*Value { + switch value.TypeId() { + case ValueId: + return nil + case StringId: + return nil + case BytesId: + return nil + case BoolId: + return nil + case NoneId: + return nil + case IntId: + return nil + case FloatId: + return nil + case ArrayId, TupleId: + return value.GetValues() + case HashId: + return nil + case BuiltInFunctionId: + return nil + case FunctionId: + return nil + case BuiltInClassId: + return nil + case ClassId: + return nil } - o.symbols.Set(symbol, object) return nil } -func (o *Value) TypeName() string { - return o.typeName +func (value *Value) Call(argument ...*Value) (*Value, error) { + return value.GetCallback()(argument...) +} + +func (value *Value) Implements(class *Value) bool { + if value == class { + return true + } + for _, base := range value.GetClassInfo().Bases { + if base.Implements(class) { + return true + } + } + return false +} + +func (value *Value) Equal(other *Value) bool { + switch value.TypeId() { + case ValueId: + return value.ValueEqual(other) + case StringId: + return value.StringEqual(other) + case BytesId: + return value.BytesEqual(other) + case BoolId: + return value.BoolEqual(other) + case NoneId: + return value.NoneEqual(other) + case IntId: + return value.IntEqual(other) + case FloatId: + return value.FloatEqual(other) + case ArrayId: + return value.ArrayEqual(other) + case TupleId: + return value.TupleEqual(other) + case HashId: + return value.HashEqual(other) + case BuiltInFunctionId: + return value.BuiltInFunctionEqual(other) + case FunctionId: + return value.FunctionEqual(other) + case BuiltInClassId: + return value.BuiltInClassEqual(other) + case ClassId: + return value.ClassEqual(other) + } + return false } -func (o *Value) SymbolTable() *SymbolTable { - return o.symbols +func (value *Value) ValueEqual(other *Value) bool { + return value == other } -func (o *Value) GetHash() int64 { - return o.hash +func (value *Value) StringEqual(other *Value) bool { + return value.String() == other.String() } -func (o *Value) SetHash(newHash int64) { - o.hash = newHash +func (value *Value) BytesEqual(other *Value) bool { + return bytes.Equal(value.GetBytes(), other.GetBytes()) } -func (o *Value) GetClass(p *Plasma) *Value { - if o.class == nil { // This should only happen with built-ins - o.class = p.ForceMasterGetAny(o.typeName) +func (value *Value) BoolEqual(other *Value) bool { + return value.Bool() == other.Bool() +} + +func (value *Value) NoneEqual(other *Value) bool { + return value == other +} + +func (value *Value) IntEqual(other *Value) bool { + switch other.TypeId() { + case IntId: + return value.Int() == other.Int() + case FloatId: + return value.Float() == other.Float() } - return o.class + return false } -func (o *Value) SetClass(class *Value) { - o.class = class +func (value *Value) FloatEqual(other *Value) bool { + switch other.TypeId() { + case IntId: + return value.Int() == other.Int() + case FloatId: + return value.Float() == other.Float() + } + return false } -func (o *Value) Implements(class *Value) bool { - if o.IsTypeById(TypeId) { - if o == class { - return true +func (value *Value) ArrayEqual(other *Value) bool { + switch other.TypeId() { + case ArrayId: + values := value.GetValues() + otherValues := other.GetValues() + if len(values) != len(otherValues) { + return false } - for _, subClass := range o.subClasses { - if subClass.Implements(class) { - return true + for index, internalValue := range values { + if !internalValue.Equal(otherValues[index]) { + return false } } - return false - } - if o.class == class { return true } - for _, subClass := range o.subClasses { - if subClass.Implements(class) { - return true + return false +} + +func (value *Value) TupleEqual(other *Value) bool { + switch other.TypeId() { + case TupleId: + values := value.GetValues() + otherValues := other.GetValues() + if len(values) != len(otherValues) { + return false + } + for index, internalValue := range values { + if !internalValue.Equal(otherValues[index]) { + return false + } } + return true } return false } -func (o *Value) IsTypeById(id uint16) bool { - return o.BuiltInTypeId == id -} - -func (p *Plasma) NewValue( - context *Context, - isBuiltIn bool, - typeName string, - subClasses []*Value, - parentSymbols *SymbolTable, -) *Value { - result := &Value{ - id: p.NextId(), - typeName: typeName, - subClasses: subClasses, - symbols: NewSymbolTable(parentSymbols), - IsBuiltIn: isBuiltIn, - onDemandSymbols: map[string]OnDemandLoader{}, - BuiltInTypeId: ValueId, - } - result.BuiltInTypeId = ValueId - result.Bool = true - result.String = "" - result.Integer = 0 - result.Float = 0 - result.Content = []*Value{} - result.KeyValues = map[int64][]*KeyValue{} - result.Bytes = []uint8{} - result.SetOnDemandSymbol(Self, - func() *Value { - return result - }, - ) - p.ObjectInitialize(isBuiltIn)(context, result) - return result -} - -func (p *Plasma) ObjectInitialize(isBuiltIn bool) ConstructorCallBack { - return func(context *Context, object *Value) *Value { - object.SetOnDemandSymbol(Initialize, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(_ *Value, _ ...*Value) (*Value, bool) { - return p.GetNone(), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Negate, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - selfBool, callError := p.QuickGetBool(context, self) - if callError != nil { - return callError, false - } - return p.InterpretAsBool(!selfBool), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(And, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - leftBool, callError := p.QuickGetBool(context, self) - if callError != nil { - return callError, false - } - var rightBool bool - rightBool, callError = p.QuickGetBool(context, arguments[0]) - if callError != nil { - return callError, false - } - return p.InterpretAsBool(leftBool && rightBool), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightAnd, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - leftBool, callError := p.QuickGetBool(context, arguments[0]) - if callError != nil { - return callError, false - } - var rightBool bool - rightBool, callError = p.QuickGetBool(context, self) - if callError != nil { - return callError, false - } - return p.InterpretAsBool(leftBool && rightBool), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Or, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - leftBool, callError := p.QuickGetBool(context, self) - if callError != nil { - return callError, false - } - var rightBool bool - rightBool, callError = p.QuickGetBool(context, arguments[0]) - if callError != nil { - return callError, false - } - return p.InterpretAsBool(leftBool || rightBool), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightOr, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - leftBool, callError := p.QuickGetBool(context, arguments[0]) - if callError != nil { - return callError, false - } - var rightBool bool - rightBool, callError = p.QuickGetBool(context, self) - if callError != nil { - return callError, false - } - return p.InterpretAsBool(leftBool || rightBool), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Xor, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - leftBool, callError := p.QuickGetBool(context, self) - if callError != nil { - return callError, false - } - var rightBool bool - rightBool, callError = p.QuickGetBool(context, arguments[0]) - if callError != nil { - return callError, false - } - return p.InterpretAsBool(leftBool != rightBool), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightXor, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - leftBool, callError := p.QuickGetBool(context, arguments[0]) - if callError != nil { - return callError, false - } - var rightBool bool - rightBool, callError = p.QuickGetBool(context, self) - if callError != nil { - return callError, false - } - return p.InterpretAsBool(leftBool != rightBool), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Equals, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - right := arguments[0] - return p.InterpretAsBool(self.Id() == right.Id()), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Equals, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - right := arguments[0] - return p.InterpretAsBool(self.Id() == right.Id()), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightEquals, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - left := arguments[0] - return p.InterpretAsBool(left.Id() == self.Id()), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(NotEquals, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - right := arguments[0] - return p.InterpretAsBool(self.Id() != right.Id()), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(RightNotEquals, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - left := arguments[0] - return p.InterpretAsBool(left.Id() != self.Id()), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Hash, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - if self.GetHash() == 0 { - objectHash := p.HashString(fmt.Sprintf("%v-%s-%d", self, self.TypeName(), self.Id())) - self.SetHash(objectHash) - } - return p.NewInteger(context, false, self.GetHash()), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(Class, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return self.GetClass(p), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(SubClasses, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - var subClassesCopy []*Value - for _, class := range self.SubClasses() { - subClassesCopy = append(subClassesCopy, class) - } - return p.NewTuple(context, false, subClassesCopy), true - }, - ), - ) - }, - ) - - object.SetOnDemandSymbol(ToString, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.NewString(context, false, - fmt.Sprintf("%s{%s}-%X", ValueName, self.TypeName(), self.Id())), true - }, - ), - ) - }) - object.SetOnDemandSymbol(ToBool, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(_ *Value, _ ...*Value) (*Value, bool) { - return p.GetTrue(), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(GetInteger, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.NewInteger(context, false, self.Integer), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(GetBool, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.InterpretAsBool(self.Bool), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(GetBytes, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.NewBytes(context, false, self.Bytes), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(GetString, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.NewString(context, false, self.String), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(GetFloat, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.NewFloat(context, false, self.Float), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(GetContent, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - return p.NewArray(context, false, self.Content), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(GetKeyValues, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 0, - func(self *Value, _ ...*Value) (*Value, bool) { - result := p.NewHashTable(context, false) - result.KeyValues = self.KeyValues - return result, true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(SetBool, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - self.Bool = arguments[0].Bool - return p.GetNone(), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(SetBytes, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - self.Bytes = arguments[0].Bytes - return p.GetNone(), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(SetString, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - self.String = arguments[0].String - return p.GetNone(), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(SetInteger, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - self.Integer = arguments[0].Integer - return p.GetNone(), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(SetFloat, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - self.Float = arguments[0].Float - return p.GetNone(), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(SetContent, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - self.Content = arguments[0].Content - return p.GetNone(), true - }, - ), - ) - }, - ) - object.SetOnDemandSymbol(SetKeyValues, - func() *Value { - return p.NewFunction(context, isBuiltIn, object.SymbolTable(), - NewBuiltInClassFunction(object, 1, - func(self *Value, arguments ...*Value) (*Value, bool) { - self.KeyValues = (arguments[0].KeyValues) - return p.GetNone(), true - }, - ), - ) - }, - ) - return nil +func (value *Value) HashEqual(other *Value) bool { + // TODO: implement me! + return value == other +} + +func (value *Value) BuiltInFunctionEqual(other *Value) bool { + return value == other +} + +func (value *Value) FunctionEqual(other *Value) bool { + return value == other +} + +func (value *Value) BuiltInClassEqual(other *Value) bool { + return value == other +} + +func (value *Value) ClassEqual(other *Value) bool { + return value == other +} + +/* +NewValue magic functions (on demand) +And __and__ +Or __or__ +Xor __xor__ +Is __is__ +Implements __implements__ +Bool __bool__ +Class __class__ +*/ +func (plasma *Plasma) NewValue(parent *Symbols, typeId TypeId, class *Value) *Value { + return &Value{ + onDemand: plasma.onDemand, + class: class, + typeId: typeId, + mutex: &sync.Mutex{}, + v: nil, + vtable: NewSymbols(parent), } } diff --git a/vendor/github.com/shoriwe/gplasma/pkg/vm/vm.go b/vendor/github.com/shoriwe/gplasma/pkg/vm/vm.go new file mode 100644 index 0000000..ca10bb5 --- /dev/null +++ b/vendor/github.com/shoriwe/gplasma/pkg/vm/vm.go @@ -0,0 +1,158 @@ +package vm + +import ( + "fmt" + "github.com/shoriwe/gplasma/pkg/compiler" + "io" +) + +type ( + Loader func(plasma *Plasma) *Value + Plasma struct { + Stdin io.Reader + Stdout, Stderr io.Writer + rootSymbols *Symbols + onDemand map[string]func(self *Value) *Value + true, false, none *Value + value *Value + string *Value + bytes *Value + bool *Value + noneType *Value + int *Value + float *Value + array *Value + tuple *Value + hash *Value + function *Value + class *Value + } +) + +func (plasma *Plasma) Symbols() *Symbols { + return plasma.rootSymbols +} + +func (plasma *Plasma) True() *Value { + return plasma.true +} + +func (plasma *Plasma) False() *Value { + return plasma.false +} + +func (plasma *Plasma) None() *Value { + return plasma.none +} + +func (plasma *Plasma) Value() *Value { + return plasma.value +} + +func (plasma *Plasma) String() *Value { + return plasma.string +} + +func (plasma *Plasma) Bytes() *Value { + return plasma.bytes +} + +func (plasma *Plasma) Bool() *Value { + return plasma.bool +} + +func (plasma *Plasma) NoneType() *Value { + return plasma.noneType +} + +func (plasma *Plasma) Int() *Value { + return plasma.int +} + +func (plasma *Plasma) Float() *Value { + return plasma.float +} + +func (plasma *Plasma) Array() *Value { + return plasma.array +} + +func (plasma *Plasma) Tuple() *Value { + return plasma.tuple +} + +func (plasma *Plasma) Hash() *Value { + return plasma.hash +} + +func (plasma *Plasma) Function() *Value { + return plasma.function +} + +func (plasma *Plasma) Class() *Value { + return plasma.class +} + +func (plasma *Plasma) executeCtx(ctx *context) { + defer func() { + err := recover() + if err != nil { + ctx.err <- fmt.Errorf("execution error: %v", err) + } else { + ctx.err <- nil + } + ctx.result <- ctx.register + return + }() + for ctx.hasNext() { + select { + case <-ctx.stop: + return + default: + plasma.do(ctx) + } + } +} + +func (plasma *Plasma) Load(symbol string, loader Loader) { + plasma.rootSymbols.Set(symbol, loader(plasma)) +} + +func (plasma *Plasma) Execute(bytecode []byte) (result chan *Value, err chan error, stop chan struct{}) { + // Create new context + ctx := plasma.newContext(bytecode) + ctx.result = make(chan *Value, 1) + ctx.err = make(chan error, 1) + ctx.stop = make(chan struct{}, 1) + // Execute bytecode with context + go plasma.executeCtx(ctx) + return ctx.result, ctx.err, ctx.stop +} + +func (plasma *Plasma) ExecuteString(scriptCode string) (result chan *Value, err chan error, stop chan struct{}) { + bytecode, compileError := compiler.Compile(scriptCode) + // Create new context + ctx := plasma.newContext(bytecode) + ctx.result = make(chan *Value, 1) + ctx.err = make(chan error, 1) + ctx.stop = make(chan struct{}, 1) + if compileError != nil { + ctx.result <- nil + ctx.err <- compileError + } else { + // Execute bytecode with context + go plasma.executeCtx(ctx) + } + return ctx.result, ctx.err, ctx.stop +} + +func NewVM(stdin io.Reader, stdout, stderr io.Writer) *Plasma { + plasma := &Plasma{ + Stdin: stdin, + Stdout: stdout, + Stderr: stderr, + rootSymbols: NewSymbols(nil), + } + plasma.init() + return plasma +} diff --git a/vendor/github.com/shoriwe/gplasma/plasma.go b/vendor/github.com/shoriwe/gplasma/plasma.go deleted file mode 100644 index 6026c16..0000000 --- a/vendor/github.com/shoriwe/gplasma/plasma.go +++ /dev/null @@ -1,60 +0,0 @@ -package gplasma - -import ( - "github.com/shoriwe/gplasma/pkg/compiler/lexer" - "github.com/shoriwe/gplasma/pkg/compiler/parser" - "github.com/shoriwe/gplasma/pkg/reader" - "github.com/shoriwe/gplasma/pkg/vm" - "os" -) - -type VirtualMachine struct { - *vm.Plasma -} - -func NewVirtualMachine() *VirtualMachine { - return &VirtualMachine{Plasma: vm.NewPlasmaVM(os.Stdin, os.Stdout, os.Stderr)} -} - -func (v *VirtualMachine) prepareCode(code string) ([]*vm.Code, *vm.Value) { - root, parsingError := parser.NewParser(lexer.NewLexer(reader.NewStringReader(code))).Parse() - if parsingError != nil { - return nil, v.NewGoRuntimeError(v.BuiltInContext, parsingError.Error()) - } - bytecode, compilationError := root.Compile() - if compilationError != nil { - return nil, v.NewGoRuntimeError(v.BuiltInContext, compilationError.Error()) - } - return bytecode, nil -} - -func (v *VirtualMachine) Execute(context *vm.Context, bytecode *vm.Bytecode) (*vm.Value, bool) { - /* - This only should be used when accessing developing a new module for the language - */ - context.PeekSymbolTable().Set(vm.IsMain, v.GetFalse()) - defer func() { - _, found := context.PeekSymbolTable().Symbols[vm.IsMain] - if found { - delete(context.PeekSymbolTable().Symbols, vm.IsMain) - } - }() - result, success := v.Plasma.Execute(context, bytecode) - return result, success -} - -func (v *VirtualMachine) ExecuteMain(mainScript string) (*vm.Value, bool) { - bytecode, preparationError := v.prepareCode(mainScript) - if preparationError != nil { - return preparationError, false - } - context := v.NewContext() - context.PeekSymbolTable().Set(vm.IsMain, v.GetTrue()) - defer func() { - _, found := context.PeekSymbolTable().Symbols[vm.IsMain] - if found { - delete(context.PeekSymbolTable().Symbols, vm.IsMain) - } - }() - return v.Plasma.Execute(context, vm.NewBytecodeFromArray(bytecode)) -} diff --git a/vendor/modules.txt b/vendor/modules.txt index 34a8670..1ae248f 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -3,15 +3,25 @@ # github.com/gorilla/websocket v1.5.0 ## explicit github.com/gorilla/websocket -# github.com/shoriwe/gplasma v0.0.0-20220517214355-8a4aa6af9004 +# github.com/otiai10/copy v1.6.0 ## explicit -github.com/shoriwe/gplasma -github.com/shoriwe/gplasma/pkg/compiler/ast -github.com/shoriwe/gplasma/pkg/compiler/lexer -github.com/shoriwe/gplasma/pkg/compiler/parser -github.com/shoriwe/gplasma/pkg/errors +# github.com/shoriwe/gplasma v1.0.1 +## explicit +github.com/shoriwe/gplasma/pkg/ast +github.com/shoriwe/gplasma/pkg/ast2 +github.com/shoriwe/gplasma/pkg/ast3 +github.com/shoriwe/gplasma/pkg/bytecode/assembler +github.com/shoriwe/gplasma/pkg/bytecode/opcodes +github.com/shoriwe/gplasma/pkg/common +github.com/shoriwe/gplasma/pkg/common/magic-functions +github.com/shoriwe/gplasma/pkg/common/special-symbols +github.com/shoriwe/gplasma/pkg/compiler +github.com/shoriwe/gplasma/pkg/lexer +github.com/shoriwe/gplasma/pkg/parser +github.com/shoriwe/gplasma/pkg/passes/checks +github.com/shoriwe/gplasma/pkg/passes/simplification +github.com/shoriwe/gplasma/pkg/passes/transformations-1 github.com/shoriwe/gplasma/pkg/reader -github.com/shoriwe/gplasma/pkg/tools github.com/shoriwe/gplasma/pkg/vm # golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 ## explicit From 2bbc2c179562d4879e10a7abe61754408c43db89 Mon Sep 17 00:00:00 2001 From: Antonio Date: Tue, 23 Aug 2022 14:40:06 -0500 Subject: [PATCH 3/4] Updated golang minimum version required --- go.mod | 16 ++++++++++------ go.sum | 22 +--------------------- vendor/github.com/gorilla/websocket/go.mod | 3 --- vendor/github.com/gorilla/websocket/go.sum | 0 vendor/gopkg.in/yaml.v3/go.mod | 5 ----- vendor/modules.txt | 13 +++++++------ 6 files changed, 18 insertions(+), 41 deletions(-) delete mode 100644 vendor/github.com/gorilla/websocket/go.mod delete mode 100644 vendor/github.com/gorilla/websocket/go.sum delete mode 100644 vendor/gopkg.in/yaml.v3/go.mod diff --git a/go.mod b/go.mod index c56a578..30fd4c8 100644 --- a/go.mod +++ b/go.mod @@ -1,14 +1,18 @@ module github.com/shoriwe/fullproxy/v3 -go 1.16 +go 1.18 require ( - github.com/elazarl/goproxy v0.0.0-20210801061803-8e322dfb79c4 // indirect - github.com/gorilla/websocket v1.5.0 // indirect - github.com/otiai10/copy v1.6.0 // indirect - github.com/shoriwe/gplasma v1.0.1 // indirect + github.com/gorilla/websocket v1.5.0 + github.com/shoriwe/gplasma v1.0.1 golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 golang.org/x/net v0.0.0-20210908191846-a5e095526f91 gopkg.in/elazarl/goproxy.v1 v1.0.0-20180725130230-947c36da3153 - gopkg.in/yaml.v3 v3.0.0-20220512140231-539c8e751b99 // indirect + gopkg.in/yaml.v3 v3.0.0-20220512140231-539c8e751b99 +) + +require ( + github.com/elazarl/goproxy v0.0.0-20210801061803-8e322dfb79c4 // indirect + github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2 // indirect + golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 // indirect ) diff --git a/go.sum b/go.sum index 814359a..a709a68 100644 --- a/go.sum +++ b/go.sum @@ -2,38 +2,18 @@ github.com/elazarl/goproxy v0.0.0-20210801061803-8e322dfb79c4 h1:lS3P5Nw3oPO05Lk github.com/elazarl/goproxy v0.0.0-20210801061803-8e322dfb79c4/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2 h1:dWB6v3RcOy03t/bUadywsbyrQwCqZeNIEX6M1OtSZOM= github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8= -github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/otiai10/copy v1.6.0/go.mod h1:XWfuS3CrI0R6IE0FbgHsEazaXO8G0LpMp9o8tos0x4E= -github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= -github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= -github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= -github.com/otiai10/mint v1.3.2/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc= -github.com/shoriwe/gplasma v0.0.0-20211103070337-347bfcd57a67 h1:T2K23Kb62Q6LXxH3s/3ymfvXkKJjORpRxaaEooKW1Ok= -github.com/shoriwe/gplasma v0.0.0-20211103070337-347bfcd57a67/go.mod h1:4Wd1xurUfcdcoJVhu++BCj4N8bfCp1hwlR+TEmqz6TA= -github.com/shoriwe/gplasma v0.0.0-20220517214355-8a4aa6af9004 h1:k07yeLPKhs7zLueZJLfLwPlVkiDchxAg5Y/SDErXJM8= -github.com/shoriwe/gplasma v0.0.0-20220517214355-8a4aa6af9004/go.mod h1:4Wd1xurUfcdcoJVhu++BCj4N8bfCp1hwlR+TEmqz6TA= github.com/shoriwe/gplasma v1.0.1 h1:q4peogYDCTSWrSKWNP8+OLvmDWMdEeS7wsT3hF69EOc= github.com/shoriwe/gplasma v1.0.1/go.mod h1:f9gs3jQQMWvY+XCbKe1oB7xpiJSuU5FjKQvP9aNs2Ko= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210908191846-a5e095526f91 h1:E8wdt+zBjoxD3MA65wEc3pl25BsTi7tbkpwc4ANThjc= golang.org/x/net v0.0.0-20210908191846-a5e095526f91/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/elazarl/goproxy.v1 v1.0.0-20180725130230-947c36da3153 h1:i2sumy6EgvN2dbX7HPhoDc7hLyoym3OYdU5HlvUUrpE= gopkg.in/elazarl/goproxy.v1 v1.0.0-20180725130230-947c36da3153/go.mod h1:xzjpkyedLMz3EXUTBbkRuuGPsxfsBX3Sy7J6kC9Gvoc= diff --git a/vendor/github.com/gorilla/websocket/go.mod b/vendor/github.com/gorilla/websocket/go.mod deleted file mode 100644 index 1a7afd5..0000000 --- a/vendor/github.com/gorilla/websocket/go.mod +++ /dev/null @@ -1,3 +0,0 @@ -module github.com/gorilla/websocket - -go 1.12 diff --git a/vendor/github.com/gorilla/websocket/go.sum b/vendor/github.com/gorilla/websocket/go.sum deleted file mode 100644 index e69de29..0000000 diff --git a/vendor/gopkg.in/yaml.v3/go.mod b/vendor/gopkg.in/yaml.v3/go.mod deleted file mode 100644 index f407ea3..0000000 --- a/vendor/gopkg.in/yaml.v3/go.mod +++ /dev/null @@ -1,5 +0,0 @@ -module "gopkg.in/yaml.v3" - -require ( - "gopkg.in/check.v1" v0.0.0-20161208181325-20d25e280405 -) diff --git a/vendor/modules.txt b/vendor/modules.txt index 1ae248f..03f3b84 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1,12 +1,12 @@ # github.com/elazarl/goproxy v0.0.0-20210801061803-8e322dfb79c4 ## explicit -# github.com/gorilla/websocket v1.5.0 +# github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2 ## explicit +# github.com/gorilla/websocket v1.5.0 +## explicit; go 1.12 github.com/gorilla/websocket -# github.com/otiai10/copy v1.6.0 -## explicit # github.com/shoriwe/gplasma v1.0.1 -## explicit +## explicit; go 1.18 github.com/shoriwe/gplasma/pkg/ast github.com/shoriwe/gplasma/pkg/ast2 github.com/shoriwe/gplasma/pkg/ast3 @@ -24,13 +24,14 @@ github.com/shoriwe/gplasma/pkg/passes/transformations-1 github.com/shoriwe/gplasma/pkg/reader github.com/shoriwe/gplasma/pkg/vm # golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 -## explicit +## explicit; go 1.17 golang.org/x/crypto/sha3 # golang.org/x/net v0.0.0-20210908191846-a5e095526f91 -## explicit +## explicit; go 1.17 golang.org/x/net/internal/socks golang.org/x/net/proxy # golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 +## explicit; go 1.17 golang.org/x/sys/cpu # gopkg.in/elazarl/goproxy.v1 v1.0.0-20180725130230-947c36da3153 ## explicit From 565870937d7c6704ffe8b913fb5748ef65eccda7 Mon Sep 17 00:00:00 2001 From: Antonio Date: Tue, 23 Aug 2022 15:12:54 -0500 Subject: [PATCH 4/4] plasma v1.0.1 adoption --- debug/main.py | 18 +++++++-------- driver.go | 22 +++++++++++-------- go.mod | 2 +- go.sum | 2 ++ sample-config/configs/sample.yaml | 4 ++-- sample-config/scripts/auth.pm | 4 ++-- sample-config/scripts/filter.pm | 4 ++-- .../shoriwe/gplasma/pkg/vm/symbol-table.go | 6 ++--- .../shoriwe/gplasma/pkg/vm/value.go | 2 +- vendor/modules.txt | 2 +- 10 files changed, 36 insertions(+), 30 deletions(-) diff --git a/debug/main.py b/debug/main.py index 232b450..d7a3ffc 100644 --- a/debug/main.py +++ b/debug/main.py @@ -54,13 +54,13 @@ def test_socks5_with_http_no_auth(): def test_socks5_with_http_with_file_auth(): - #assert requests.get( - # "http://127.0.0.1:8080", - # proxies={ - # "http": "socks5://sulcud:password@127.0.0.1:9050", - # "https": "socks5://sulcud:password@127.0.0.1:9050" - # } - #) + # assert requests.get( + # "http://127.0.0.1:8000", + # proxies={ + # "http": "socks5://sulcud:password@127.0.0.1:9050", + # "https": "socks5://sulcud:password@127.0.0.1:9050" + # } + # ) assert requests.get( "https://google.com", proxies={ @@ -77,8 +77,8 @@ def main(): # test_socks5_with_http_no_auth() - test_http_with_http_no_auth() -# test_socks5_with_http_with_file_auth() + #test_http_with_http_no_auth() + test_socks5_with_http_with_file_auth() if __name__ == '__main__': diff --git a/driver.go b/driver.go index 4c3a355..c04db65 100644 --- a/driver.go +++ b/driver.go @@ -19,7 +19,7 @@ var ( func authScript(username, password []byte) []byte { bytecode, _ := assembler.Assemble( ast3.Program{ - ast3.Call{ + &ast3.Call{ Function: &ast3.Selector{ X: &ast3.Identifier{ Symbol: "-driver", @@ -45,7 +45,7 @@ func authScript(username, password []byte) []byte { func inboundScript(address []byte) []byte { bytecode, _ := assembler.Assemble( ast3.Program{ - ast3.Call{ + &ast3.Call{ Function: &ast3.Selector{ X: &ast3.Identifier{ Symbol: "-driver", @@ -68,7 +68,7 @@ func inboundScript(address []byte) []byte { func outboundScript(address []byte) []byte { bytecode, _ := assembler.Assemble( ast3.Program{ - ast3.Call{ + &ast3.Call{ Function: &ast3.Selector{ X: &ast3.Identifier{ Symbol: "-driver", @@ -91,7 +91,7 @@ func outboundScript(address []byte) []byte { func listenScript(address []byte) []byte { bytecode, _ := assembler.Assemble( ast3.Program{ - ast3.Call{ + &ast3.Call{ Function: &ast3.Selector{ X: &ast3.Identifier{ Symbol: "-driver", @@ -114,7 +114,7 @@ func listenScript(address []byte) []byte { func acceptScript(address []byte) []byte { bytecode, _ := assembler.Assemble( ast3.Program{ - ast3.Call{ + &ast3.Call{ Function: &ast3.Selector{ X: &ast3.Identifier{ Symbol: "-driver", @@ -238,23 +238,27 @@ func (d *Driver) Accept(address string) error { return nil } -func (r *runner) loadDriver(script string) (*Driver, error) { +func (r *runner) loadDriver(scriptPath string) (*Driver, error) { + scriptContents, readError := os.ReadFile(scriptPath) + if readError != nil { + return nil, readError + } d := &Driver{ plasma: initializeVM(), } // Setup the names used by the script - _, errorChannel, _ := d.plasma.ExecuteString(script) + _, errorChannel, _ := d.plasma.ExecuteString(string(scriptContents)) // if err := <-errorChannel; err != nil { - return nil, errors.New("driver script execution error") + return nil, err } return d, nil } func initializeVM() *vm.Plasma { plasma := vm.NewVM(os.Stdin, os.Stdout, os.Stderr) - plasma.Load("-driver", func(_ *vm.Plasma) *vm.Value { return plasma.None() }) + plasma.Load("-driver", func(_ *vm.Plasma) *vm.Value { return plasma.Value() }) plasma.Load("set_auth", func(p *vm.Plasma) *vm.Value { return p.NewBuiltInFunction( diff --git a/go.mod b/go.mod index 30fd4c8..2d12939 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.18 require ( github.com/gorilla/websocket v1.5.0 - github.com/shoriwe/gplasma v1.0.1 + github.com/shoriwe/gplasma v1.0.2 golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 golang.org/x/net v0.0.0-20210908191846-a5e095526f91 gopkg.in/elazarl/goproxy.v1 v1.0.0-20180725130230-947c36da3153 diff --git a/go.sum b/go.sum index a709a68..2d13ea8 100644 --- a/go.sum +++ b/go.sum @@ -7,6 +7,8 @@ github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/ad github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc= github.com/shoriwe/gplasma v1.0.1 h1:q4peogYDCTSWrSKWNP8+OLvmDWMdEeS7wsT3hF69EOc= github.com/shoriwe/gplasma v1.0.1/go.mod h1:f9gs3jQQMWvY+XCbKe1oB7xpiJSuU5FjKQvP9aNs2Ko= +github.com/shoriwe/gplasma v1.0.2 h1:M3+Q6WzYjxVwoCpq6mZWpufLV42SB88ViSFnzC3h4QE= +github.com/shoriwe/gplasma v1.0.2/go.mod h1:f9gs3jQQMWvY+XCbKe1oB7xpiJSuU5FjKQvP9aNs2Ko= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/net v0.0.0-20210908191846-a5e095526f91 h1:E8wdt+zBjoxD3MA65wEc3pl25BsTi7tbkpwc4ANThjc= diff --git a/sample-config/configs/sample.yaml b/sample-config/configs/sample.yaml index 92f51d9..d47f813 100644 --- a/sample-config/configs/sample.yaml +++ b/sample-config/configs/sample.yaml @@ -20,8 +20,8 @@ services: network: tcp address: 127.0.0.1:9050 filters: - #inbound: filter - #outbound: filter + # inbound: filter + outbound: filter listen: filter accept: filter protocol: diff --git a/sample-config/scripts/auth.pm b/sample-config/scripts/auth.pm index 6e16b58..371b95c 100644 --- a/sample-config/scripts/auth.pm +++ b/sample-config/scripts/auth.pm @@ -1,8 +1,8 @@ def basic_login(username, password) if username == "sulcud" and password == "password" - return True + return true end - return False + return false end set_auth(basic_login) \ No newline at end of file diff --git a/sample-config/scripts/filter.pm b/sample-config/scripts/filter.pm index e500b2f..07d848e 100644 --- a/sample-config/scripts/filter.pm +++ b/sample-config/scripts/filter.pm @@ -1,10 +1,10 @@ def no_localhost(address) if "127.0.0.1" in address - return False + return false elif "localhost" in address return false end - return True + return true end set_inbound(no_localhost) diff --git a/vendor/github.com/shoriwe/gplasma/pkg/vm/symbol-table.go b/vendor/github.com/shoriwe/gplasma/pkg/vm/symbol-table.go index 7246969..c0b9018 100644 --- a/vendor/github.com/shoriwe/gplasma/pkg/vm/symbol-table.go +++ b/vendor/github.com/shoriwe/gplasma/pkg/vm/symbol-table.go @@ -6,7 +6,7 @@ import ( ) var ( - SymbolNotFoundError = fmt.Errorf("symbol not found") + SymbolNotFoundError = "symbol not found: %s" ) type ( @@ -50,7 +50,7 @@ func (symbols *Symbols) Get(name string) (*Value, error) { return value, nil } } - return nil, SymbolNotFoundError + return nil, fmt.Errorf(SymbolNotFoundError, name) } func (symbols *Symbols) Del(name string) error { @@ -58,7 +58,7 @@ func (symbols *Symbols) Del(name string) error { defer symbols.mutex.Unlock() _, found := symbols.values[name] if !found { - return SymbolNotFoundError + return fmt.Errorf(SymbolNotFoundError, name) } delete(symbols.values, name) return nil diff --git a/vendor/github.com/shoriwe/gplasma/pkg/vm/value.go b/vendor/github.com/shoriwe/gplasma/pkg/vm/value.go index 199082b..8a5a8ef 100644 --- a/vendor/github.com/shoriwe/gplasma/pkg/vm/value.go +++ b/vendor/github.com/shoriwe/gplasma/pkg/vm/value.go @@ -151,7 +151,7 @@ func (value *Value) Get(symbol string) (*Value, error) { defer value.mutex.Unlock() onDemand, found := value.onDemand[symbol] if !found { - return nil, SymbolNotFoundError + return nil, fmt.Errorf(SymbolNotFoundError, symbol) } result = onDemand(value) value.vtable.Set(symbol, result) diff --git a/vendor/modules.txt b/vendor/modules.txt index 03f3b84..41bb8e2 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -5,7 +5,7 @@ # github.com/gorilla/websocket v1.5.0 ## explicit; go 1.12 github.com/gorilla/websocket -# github.com/shoriwe/gplasma v1.0.1 +# github.com/shoriwe/gplasma v1.0.2 ## explicit; go 1.18 github.com/shoriwe/gplasma/pkg/ast github.com/shoriwe/gplasma/pkg/ast2