diff options
-rw-r--r-- | README.md | 3 | ||||
-rw-r--r-- | src/tparse/token.go | 5 | ||||
-rw-r--r-- | src/tparse/tree.go | 76 | ||||
-rw-r--r-- | src/tparse/type.go | 3 |
4 files changed, 73 insertions, 14 deletions
@@ -1,3 +1,6 @@ # tnsl-parse The tokenizer for the [TNSL Language](https://github.com/CoreChg/tnsl-lang). Written in Go for the moment. + +The goal is to get this part written, and then write a backend for any arch (x86, arm, risc-v, etc.). +After that, work can begin on the real parser which will be written in native TNSL
\ No newline at end of file diff --git a/src/tparse/token.go b/src/tparse/token.go index f923af4..51a2123 100644 --- a/src/tparse/token.go +++ b/src/tparse/token.go @@ -30,3 +30,8 @@ type Node struct { Data Token Sub []Node } + +func makeParent(parent *Node, child Node) { + child.Parent = parent + parent.Sub = append(parent.Sub, child) +} diff --git a/src/tparse/tree.go b/src/tparse/tree.go index 748ca90..c0da5c2 100644 --- a/src/tparse/tree.go +++ b/src/tparse/tree.go @@ -26,22 +26,55 @@ func errOut(message string, token Token) { panic(token) } -func tree(tokens *[]Token, tok, max int) (Node, int) { +// Parses a list of things as parameters +func parseList(tokens *[]Token, tok, max int, param bool) (Node, int) { out := Node{} + out.Data = Token{Type: 10, Data: "list"} + + currentType := Node{} + currentType.Data = Token{Data: "undefined"} for ; tok < max; tok++ { - //t := (*tokens)[tok] - } + t0 := (*tokens)[tok] + t1 := (*tokens)[tok+1] - return out, tok -} + switch t1.Data { + case ")", "]", "}": + case ",": + default: + currentType, tok = parseType(tokens, tok, max, true) + t0 = (*tokens)[tok] + t1 = (*tokens)[tok+1] + } -func parseList(tokens *[]Token, tok, max int) (Node, int) { - out := Node{} - out.Data = Token{Type: 10, Data: "list"} + switch t0.Type { + case DEFWORD: + var tmp Node + if currentType.Data.Data == "undefined" { + errOut("Error: expected type before first parameter", t0) + } else if currentType.Data.Data == "type" { + tmp, tok = parseType(tokens, tok, max, true) + } else { + tmp = Node{Data: t0} + } - for ; tok < max; tok++ { - //t := (*tokens)[tok] + typ := currentType + makeParent(&typ, tmp) + makeParent(&out, typ) + + default: + errOut("Error: unexpected token when parsing list, expected user-defined variable", t0) + } + + switch t1.Data { + case ")", "]", "}": + return out, tok + case ",": + default: + errOut("Error: unexpected token when parsing list, expected ',' or end of list", t1) + } + + tok++ } return out, tok @@ -64,7 +97,7 @@ func parseTypeList(tokens *[]Token, tok, max int) (Node, int) { errOut("Error: unexpected token when parsing a list of types", t) } - tmp, tok = parseType(tokens, tok, max) + tmp, tok = parseType(tokens, tok, max, true) out.Sub = append(out.Sub, tmp) } @@ -81,7 +114,7 @@ func parseVoidType(tokens *[]Token, tok, max int) (Node, int) { return out, tok } -func parseType(tokens *[]Token, tok, max int) (Node, int) { +func parseType(tokens *[]Token, tok, max int, param bool) (Node, int) { out := Node{} working := &out @@ -109,15 +142,30 @@ func parseType(tokens *[]Token, tok, max int) (Node, int) { } case KEYWORD: - if t.Data != "const" && t.Data != "volatile" { + if param && t.Data == "static" { + errOut("Error: parameter types cannot be static", t) + } else if t.Data != "const" && t.Data != "volatile" && t.Data != "static" { errOut("Error: unexpected keyword when parsing type", t) } working.Data = t + case DELIMIT: + if t.Data == "{" { + if (*tokens)[tok+1].Data == "}" { + working.Data = Token{9, "array", t.Line, t.Char} + tok++ + } else { + errOut("Error: start of list when parsing type (did you mean {} ?)", t) + } + } else { + errOut("Error: start of list when parsing type", t) + } + default: errOut("Error: unexpected token when parsing type", t) } - working.Sub = append(working.Sub, Node{}) + + working.Sub = append(working.Sub, Node{Parent: working}) working = &(working.Sub[0]) } diff --git a/src/tparse/type.go b/src/tparse/type.go index cd4f536..b66668c 100644 --- a/src/tparse/type.go +++ b/src/tparse/type.go @@ -123,6 +123,9 @@ var RESWORD = map[string]int{ "false": LITERAL, "delete": KEYWORD, + + "module": KEYWORD, + "export": KEYWORD, } func checkResWord(s string) int { |