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