Add Location type and support to ILocatable

This commit is contained in:
Sameer Rahmani 2020-11-23 12:30:02 +00:00
parent a2725ba412
commit 57714accfc
8 changed files with 54 additions and 16 deletions

View File

@ -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,
}
}

View File

@ -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 {

View File

@ -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

View File

@ -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 {

View File

@ -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 {

View File

@ -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
}

View File

@ -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,
}
}

View File

@ -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),
}
}