parser: add comments and [...]; main: add file mode

This commit is contained in:
2018-05-14 00:37:14 +02:00
parent 3386ec0c4b
commit 8cb7c37096
3 changed files with 84 additions and 6 deletions

View File

@@ -2,6 +2,7 @@ package parser
import (
"errors"
"regexp"
"strconv"
"strings"
@@ -18,8 +19,18 @@ func withoutEmpty(input []string) []string {
return r
}
var comments = regexp.MustCompile(";.*")
var whitespace = regexp.MustCompile("\\s")
func explode(s string, start string, end string) string {
return strings.Replace(strings.Replace(s, start, " "+start+" ", -1), end, " "+end+" ", -1)
}
func tokenize(input string) []string {
return withoutEmpty(strings.Split(strings.Replace(strings.Replace(input, "(", " ( ", -1), ")", " ) ", -1), " "))
withoutComments := string(comments.ReplaceAll([]byte(input), []byte("")))
explodedParens := explode(withoutComments, "(", ")")
explodedBrackets := explode(explodedParens, "[", "]")
return withoutEmpty(whitespace.Split(explodedBrackets, -1))
}
func parseValue(input []string) (*ast.AST, error, []string) {
@@ -53,9 +64,16 @@ func parseValue(input []string) (*ast.AST, error, []string) {
return &res, nil, input[1:]
}
func makeFn(bodyStatements []ast.AST) ast.AST {
body := ast.AST{ast.List, bodyStatements}
args := ast.AST{ast.List, []ast.AST{ast.AST{ast.Symbol, "_"}}}
return ast.AST{ast.List, []ast.AST{ast.AST{ast.Symbol, "fn"}, args, body}}
}
func parseToken(input []string) (*ast.AST, error, []string) {
if len(input) == 0 {
return nil, errors.New("Unmatched '('"), input
return nil, errors.New("Unmatched '(' or '['"), input
}
if input[0][0] == '\'' {
@@ -94,6 +112,25 @@ func parseToken(input []string) (*ast.AST, error, []string) {
case ")": {
return nil, errors.New("Unmatched ')'"), input
}
case "[": {
var l []ast.AST
input = input[1:]
for input[0] != "]" {
elem, err, newInput := parseToken(input)
if err != nil {
return nil, err, input
}
l = append(l, *elem)
input = newInput
}
res := makeFn(l)
return &res, nil, input[1:]
}
case "]": {
return nil, errors.New("Unmatched ']'"), input
}
}
return parseValue(input)
}