diff --git a/bootstrap/pkg/ast/ast.go b/bootstrap/pkg/ast/ast.go index b930ac4..b8f70cd 100644 --- a/bootstrap/pkg/ast/ast.go +++ b/bootstrap/pkg/ast/ast.go @@ -32,10 +32,32 @@ const ( Block // Dont' mistake it with block from other programming languages ) +type Location struct { + start int + end int + source *[]string + knownLocation bool +} + type ILocatable interface { - GetLocation() int + GetLocation() Location +} + +func MakeLocation(input *[]string, start int, end int) Location { + return Location{ + source: input, + start: start, + end: end, + knownLocation: true, + } } type ITypable interface { GetType() NodeType } + +func MakeUnknownLocation() Location { + return Location{ + knownLocation: false, + } +} diff --git a/bootstrap/pkg/core/block.go b/bootstrap/pkg/core/block.go index 160b7c5..c0483a8 100644 --- a/bootstrap/pkg/core/block.go +++ b/bootstrap/pkg/core/block.go @@ -49,11 +49,11 @@ func (b *Block) ToDebugStr() string { return fmt.Sprintf("%#v", b) } -func (b *Block) GetLocation() int { +func (b *Block) GetLocation() ast.Location { if len(b.body) > 0 { return b.body[0].GetLocation() } - return -1 + return ast.MakeUnknownLocation() } func (b *Block) ToSlice() []IExpr { diff --git a/bootstrap/pkg/core/function.go b/bootstrap/pkg/core/function.go index 0e5c12f..e3372f0 100644 --- a/bootstrap/pkg/core/function.go +++ b/bootstrap/pkg/core/function.go @@ -90,7 +90,6 @@ func MakeFunction(scope IScope, params IColl, body *Block) *Function { // MakeFnScope a new scope for the body of a function. It binds the `bindings` // to the given `values`. func MakeFnScope(parent IScope, bindings IColl, values IColl) (*Scope, error) { - fmt.Printf("%s %s\n", bindings, values) scope := MakeScope(parent.(*Scope)) // TODO: Implement destructuring diff --git a/bootstrap/pkg/core/nil.go b/bootstrap/pkg/core/nil.go index 0eb3fa0..f62d119 100644 --- a/bootstrap/pkg/core/nil.go +++ b/bootstrap/pkg/core/nil.go @@ -29,8 +29,8 @@ func (n NilType) GetType() ast.NodeType { return ast.Nil } -func (n NilType) GetLocation() int { - return 0 +func (n NilType) GetLocation() ast.Location { + return ast.MakeUnknownLocation() } func (n NilType) String() string { diff --git a/bootstrap/pkg/core/nothing.go b/bootstrap/pkg/core/nothing.go index b17e3e6..db62b63 100644 --- a/bootstrap/pkg/core/nothing.go +++ b/bootstrap/pkg/core/nothing.go @@ -28,8 +28,8 @@ func (n NothingType) GetType() ast.NodeType { return ast.Nothing } -func (n NothingType) GetLocation() int { - return -1 +func (n NothingType) GetLocation() ast.Location { + return ast.MakeUnknownLocation() } func (n NothingType) String() string { diff --git a/bootstrap/pkg/core/parser.go b/bootstrap/pkg/core/parser.go index 6ea67d9..f3741e0 100644 --- a/bootstrap/pkg/core/parser.go +++ b/bootstrap/pkg/core/parser.go @@ -32,6 +32,7 @@ type IParsable interface { peek(skipWhitespace bool) *string back() GetLocation() int + Buffer() *[]string } type StringParser struct { @@ -81,6 +82,10 @@ func (sp *StringParser) GetLocation() int { return sp.pos } +func (sp *StringParser) Buffer() *[]string { + return &sp.buffer +} + // END: IParsable --- func contains(s []rune, c rune) bool { @@ -132,7 +137,8 @@ func readRawSymbol(parser IParsable) (IExpr, error) { } // TODO: Add support for ns qualified symbols - return MakeSymbol(symbol), nil + node := MakeNode(parser.Buffer(), parser.GetLocation()-len(symbol), parser.GetLocation()) + return MakeSymbol(node, symbol), nil } func readNumber(parser IParsable, neg bool) (IExpr, error) { @@ -252,8 +258,9 @@ func readQuotedExpr(parser IParsable) (IExpr, error) { return nil, err } + symNode := MakeNode(parser.Buffer(), parser.GetLocation(), parser.GetLocation()) return MakeList([]IExpr{ - MakeSymbol("quote"), + MakeSymbol(symNode, "quote"), expr, }), nil } @@ -269,13 +276,15 @@ func readUnquotedExpr(parser IParsable) (IExpr, error) { var err error var expr IExpr + node := MakeNode(parser.Buffer(), parser.GetLocation(), parser.GetLocation()) + if *c == "@" { parser.next(true) - sym = MakeSymbol("unquote-splicing") + sym = MakeSymbol(node, "unquote-splicing") expr, err = readExpr(parser) } else { - sym = MakeSymbol("unquote") + sym = MakeSymbol(node, "unquote") expr, err = readExpr(parser) } @@ -292,8 +301,9 @@ func readQuasiquotedExpr(parser IParsable) (IExpr, error) { return nil, err } + node := MakeNode(parser.Buffer(), parser.GetLocation(), parser.GetLocation()) return MakeList([]IExpr{ - MakeSymbol("quasiquote"), + MakeSymbol(node, "quasiquote"), expr, }), nil } diff --git a/bootstrap/pkg/core/symbol.go b/bootstrap/pkg/core/symbol.go index 40c485f..a6cbf16 100644 --- a/bootstrap/pkg/core/symbol.go +++ b/bootstrap/pkg/core/symbol.go @@ -52,8 +52,9 @@ func (s *Symbol) IsRestable() bool { return strings.HasPrefix(s.name, "&") } -func MakeSymbol(s string) *Symbol { +func MakeSymbol(n Node, s string) *Symbol { return &Symbol{ + Node: n, name: s, } } diff --git a/bootstrap/pkg/core/types.go b/bootstrap/pkg/core/types.go index 7313014..41fb5c6 100644 --- a/bootstrap/pkg/core/types.go +++ b/bootstrap/pkg/core/types.go @@ -50,10 +50,16 @@ type IExpr interface { // Node struct is simply representing a Node in the AST which provides the // functionalities required to trace the code based on the location. type Node struct { - location int + location ast.Location } // GetLocation returns the location of the Node in the source input -func (n Node) GetLocation() int { +func (n Node) GetLocation() ast.Location { return n.location } + +func MakeNode(input *[]string, start int, end int) Node { + return Node{ + location: ast.MakeLocation(input, start, end), + } +}