From 2f6f79fe35cc64381bb0c21d36cd39a28457cd85 Mon Sep 17 00:00:00 2001 From: Sameer Rahmani Date: Mon, 11 Jan 2021 19:03:02 +0000 Subject: [PATCH] Split up the ast.go into smaller files --- bootstrap/pkg/ast/ast.go | 161 ---------------------------------- bootstrap/pkg/ast/location.go | 98 +++++++++++++++++++++ bootstrap/pkg/ast/source.go | 118 +++++++++++++++++++++++++ 3 files changed, 216 insertions(+), 161 deletions(-) create mode 100644 bootstrap/pkg/ast/location.go create mode 100644 bootstrap/pkg/ast/source.go diff --git a/bootstrap/pkg/ast/ast.go b/bootstrap/pkg/ast/ast.go index 20e3de2..189e73c 100644 --- a/bootstrap/pkg/ast/ast.go +++ b/bootstrap/pkg/ast/ast.go @@ -20,11 +20,6 @@ along with this program. If not, see . // Serene's AST. package ast -import ( - "sort" - "strings" -) - type NodeType int const ( @@ -45,162 +40,6 @@ const ( ) -type Source struct { - Buffer *[]string - - // The namespace name which this source is describing - NS string - LineIndex *[]int -} - -func (s *Source) GetPos(start, end int) *string { - if start < len(*s.Buffer) && start >= 0 && end < len(*s.Buffer) && end > 0 && start <= end { - result := strings.Join((*s.Buffer)[start:end], "") - return &result - } else { - return nil - } -} -func (s *Source) GetLine(linenum int) string { - lines := strings.Split(strings.Join(*s.Buffer, ""), "\n") - if linenum > 0 && linenum <= len(lines) { - return lines[linenum-1] - } - return "----" -} - -func (s *Source) LineNumberFor(pos int) int { - - // Some dirty print debugger code - // for i, r := range *s.LineIndex { - // empty := "" - // var line *string - // var num int - // if i == 0 { - // line = s.GetPos(0, r) - // num = 0 - // } else { - // line = s.GetPos((*s.LineIndex)[i-1], r) - // num = (*s.LineIndex)[i-1] - - // } - - // if line == nil { - // line = &empty - // } - - // fmt.Print(">>>> ", num, r, *line) - // } - - if pos < 0 { - return -1 - } - - result := sort.SearchInts(*s.LineIndex, pos) - - // We've found something - if result > -1 { - // Since line numbers start from 1 unlike arrays :)) - result += 1 - } - - return result -} - -var builtinSource *Source - -func GetBuiltinSource() *Source { - if builtinSource == nil { - buf := strings.Split("builtin", "") - lineindex := []int{len(buf) - 1} - builtinSource = &Source{ - Buffer: &buf, - NS: "Serene.builtins", - LineIndex: &lineindex, - } - } - return builtinSource -} - -type Location struct { - start int - end int - source Source - knownLocation bool -} - -var UnknownLocation *Location = &Location{knownLocation: false} - -func (l *Location) GetStart() int { - return l.start -} - -func (l *Location) GetEnd() int { - return l.end -} - -func (l *Location) GetSource() *Source { - if l.IsKnownLocaiton() { - return &l.source - } - return GetBuiltinSource() -} - -func (l *Location) IncStart(x int) { - if x+l.start < len(*l.source.Buffer) { - l.start += x - } else { - l.start = len(*l.source.Buffer) - 1 - } -} - -func (l *Location) DecStart(x int) { - if l.start-x >= 0 { - l.start -= x - } else { - l.start = 0 - } - -} - -func (l *Location) IncEnd(x int) { - if x+l.end < len(*l.source.Buffer) { - l.end += x - } else { - l.end = len(*l.source.Buffer) - 1 - } - -} - -func (l *Location) DecEnd(x int) { - if l.end-x >= 0 { - l.end -= x - } else { - l.end = 0 - } -} - -func (l *Location) IsKnownLocaiton() bool { - return l.knownLocation -} - -type ILocatable interface { - GetLocation() *Location -} - -func MakeLocation(input *Source, start int, end int) *Location { - return &Location{ - source: *input, - start: start, - end: end, - knownLocation: true, - } -} - type ITypable interface { GetType() NodeType } - -func MakeUnknownLocation() *Location { - return UnknownLocation -} diff --git a/bootstrap/pkg/ast/location.go b/bootstrap/pkg/ast/location.go new file mode 100644 index 0000000..7b3921c --- /dev/null +++ b/bootstrap/pkg/ast/location.go @@ -0,0 +1,98 @@ +/* + Serene --- Yet an other Lisp + +Copyright (c) 2020 Sameer Rahmani + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +package ast + +type Location struct { + start int + end int + source Source + knownLocation bool +} + +var UnknownLocation *Location = &Location{knownLocation: false} + +func (l *Location) GetStart() int { + return l.start +} + +func (l *Location) GetEnd() int { + return l.end +} + +func (l *Location) GetSource() *Source { + if l.IsKnownLocaiton() { + return &l.source + } + return GetBuiltinSource() +} + +func (l *Location) IncStart(x int) { + if x+l.start < len(*l.source.Buffer) { + l.start += x + } else { + l.start = len(*l.source.Buffer) - 1 + } +} + +func (l *Location) DecStart(x int) { + if l.start-x >= 0 { + l.start -= x + } else { + l.start = 0 + } + +} + +func (l *Location) IncEnd(x int) { + if x+l.end < len(*l.source.Buffer) { + l.end += x + } else { + l.end = len(*l.source.Buffer) - 1 + } + +} + +func (l *Location) DecEnd(x int) { + if l.end-x >= 0 { + l.end -= x + } else { + l.end = 0 + } +} + +func (l *Location) IsKnownLocaiton() bool { + return l.knownLocation +} + +type ILocatable interface { + GetLocation() *Location +} + +func MakeLocation(input *Source, start int, end int) *Location { + return &Location{ + source: *input, + start: start, + end: end, + knownLocation: true, + } +} + +func MakeUnknownLocation() *Location { + return UnknownLocation +} diff --git a/bootstrap/pkg/ast/source.go b/bootstrap/pkg/ast/source.go new file mode 100644 index 0000000..6ce4eec --- /dev/null +++ b/bootstrap/pkg/ast/source.go @@ -0,0 +1,118 @@ +/* + Serene --- Yet an other Lisp + +Copyright (c) 2020 Sameer Rahmani + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +package ast + +// The Source data structure is used to track expression back to the source +// code. For example to find which source (file) they belongs to. + +import ( + "sort" + "strings" +) + +var builtinSource *Source + +type Source struct { + // A Pointer to the buffer where the parser used for parsing the source + Buffer *[]string + + // The namespace name which this source is describing + NS string + + // This array contains the boundaries of each line in the buffer. For example + // [24 50 106] means that the buffer contains 3 lines and the first line can + // be found from the index 0 to index 24 of the buffer and the second line is + // from index 25 till 50 and so on + LineIndex *[]int +} + +// GetSubstr returns the a pointer to the string from the buffer specified by the `start` and `end` +func (s *Source) GetSubstr(start, end int) *string { + if start < len(*s.Buffer) && start >= 0 && end < len(*s.Buffer) && end > 0 && start <= end { + result := strings.Join((*s.Buffer)[start:end], "") + return &result + } else { + return nil + } +} + +// GetLine returns the line specified by the `linenum` from the buffer. It will return "----" if the +// given line number exceeds the boundaries of the buffer +func (s *Source) GetLine(linenum int) string { + lines := strings.Split(strings.Join(*s.Buffer, ""), "\n") + if linenum > 0 && linenum <= len(lines) { + return lines[linenum-1] + } + return "----" +} + +// LineNumberFor returns the line number associated with the given position `pos` in +// the buffer +func (s *Source) LineNumberFor(pos int) int { + + // Some dirty print debugger code + // for i, r := range *s.LineIndex { + // empty := "" + // var line *string + // var num int + // if i == 0 { + // line = s.GetSubstr(0, r) + // num = 0 + // } else { + // line = s.GetSubstr((*s.LineIndex)[i-1], r) + // num = (*s.LineIndex)[i-1] + + // } + + // if line == nil { + // line = &empty + // } + + // fmt.Print(">>>> ", num, r, *line) + // } + + if pos < 0 { + return -1 + } + + result := sort.SearchInts(*s.LineIndex, pos) + + // We've found something + if result > -1 { + // Since line numbers start from 1 unlike arrays :)) + result += 1 + } + + return result +} + +// GetBuiltinSource returns a pointer to a source that represents builtin +// expressions +func GetBuiltinSource() *Source { + if builtinSource == nil { + buf := strings.Split("builtin", "") + lineindex := []int{len(buf) - 1} + builtinSource = &Source{ + Buffer: &buf, + NS: "Serene.builtins", + LineIndex: &lineindex, + } + } + return builtinSource +}