diff options
-rw-r--r-- | src/tparse/tree-list.go | 124 | ||||
-rw-r--r-- | src/tparse/tree-statement.go | 17 | ||||
-rw-r--r-- | src/tparse/tree-value.go | 100 | ||||
-rw-r--r-- | src/tparse/tree.go | 205 |
4 files changed, 253 insertions, 193 deletions
diff --git a/src/tparse/tree-list.go b/src/tparse/tree-list.go new file mode 100644 index 0000000..70f5fff --- /dev/null +++ b/src/tparse/tree-list.go @@ -0,0 +1,124 @@ +/* + Copyright 2020 Kyle Gunger + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package tparse + +// Parse a list of values +func parseValueList(tokens *[]Token, tok, max int) (Node, int) { + out := Node{} + out.Data = Token{Type: 10, Data: "list"} + var tmp Node + + tok++ + + for ; tok < max; tok++ { + t := (*tokens)[tok] + + switch t.Data { + case ")", "]", "}": + return out, tok + case ",": + tok++ + default: + errOut("Error: unexpected token when parsing a list of values", t) + } + + tmp, tok = parseValue(tokens, tok, max) + out.Sub = append(out.Sub, tmp) + } + + return out, tok +} + +// Parses a list of things +func parseDefList(tokens *[]Token, tok, max int) (Node, int) { + out := Node{} + out.Data = Token{Type: 9, Data: "list"} + + currentType := Node{} + currentType.Data = Token{Data: "undefined"} + + for ; tok < max; tok++ { + t0 := (*tokens)[tok] + t1 := (*tokens)[tok+1] + + switch t1.Data { + case ")", "]", "}", ",": + default: + currentType, tok = parseType(tokens, tok, max, true) + t0 = (*tokens)[tok] + t1 = (*tokens)[tok+1] + } + + 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} + } + + typ := currentType + makeParent(&typ, tmp) + makeParent(&out, typ) + + default: + errOut("Error: unexpected token when parsing list, expected user-defined variable or ", 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 +} + +func parseTypeList(tokens *[]Token, tok, max int) (Node, int) { + out := Node{} + out.Data = Token{Type: 9, Data: "list"} + var tmp Node + + tok++ + + for ; tok < max; tok++ { + t := (*tokens)[tok] + + switch t.Data { + case ")", "]", "}": + return out, tok + case ",": + tok++ + default: + errOut("Error: unexpected token when parsing a list of types", t) + } + + tmp, tok = parseType(tokens, tok, max, true) + out.Sub = append(out.Sub, tmp) + } + + return out, tok +} diff --git a/src/tparse/tree-statement.go b/src/tparse/tree-statement.go new file mode 100644 index 0000000..9d0b0d6 --- /dev/null +++ b/src/tparse/tree-statement.go @@ -0,0 +1,17 @@ +/* + Copyright 2020 Kyle Gunger + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package tparse diff --git a/src/tparse/tree-value.go b/src/tparse/tree-value.go new file mode 100644 index 0000000..1a057d4 --- /dev/null +++ b/src/tparse/tree-value.go @@ -0,0 +1,100 @@ +/* + Copyright 2020 Kyle Gunger + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package tparse + +func parseValue(tokens *[]Token, tok, max int) (Node, int) { + out := Node{} + + for ; tok < max; tok++ { + t := (*tokens)[tok] + switch t.Type { + case LITERAL: + case DEFWORD: + case DELIMIT: + } + } + + return out, tok +} + +func parseVoidType(tokens *[]Token, tok, max int) (Node, int) { + out := Node{} + + for ; tok < max; tok++ { + //t := (*tokens)[tok] + } + + return out, tok +} + +func parseType(tokens *[]Token, tok, max int, param bool) (Node, int) { + out := Node{} + working := &out + + for ; tok < max; tok++ { + t := (*tokens)[tok] + switch t.Type { + case AUGMENT: + if t.Data != "~" { + errOut("Error: unexpected augment token when parsing type", t) + } + working.Data = t + + case KEYTYPE: + if t.Data == "void" { + *working, tok = parseVoidType(tokens, tok, max) + } else { + working.Data = t + } + + return out, tok + + case DEFWORD: + if (*tokens)[tok+1].Data == "(" { + + } + + case KEYWORD: + 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) + } + + makeParent(working, Node{}) + working = &(working.Sub[0]) + } + + return out, tok +} diff --git a/src/tparse/tree.go b/src/tparse/tree.go index ed19e6d..0b7baf4 100644 --- a/src/tparse/tree.go +++ b/src/tparse/tree.go @@ -26,210 +26,29 @@ func errOut(message string, token Token) { panic("AST Error") } -// Parse a list of values -func parseValueList(tokens *[]Token, tok, max int) (Node, int) { - out := Node{} - out.Data = Token{Type: 10, Data: "list"} - var tmp Node - - tok++ - - for ; tok < max; tok++ { - t := (*tokens)[tok] - - switch t.Data { - case ")", "]", "}": - return out, tok - case ",": - tok++ - default: - errOut("Error: unexpected token when parsing a list of values", t) - } - - tmp, tok = parseValue(tokens, tok, max) - out.Sub = append(out.Sub, tmp) - } - - return out, tok -} - -// Parses a list of things -func parseDefList(tokens *[]Token, tok, max int) (Node, int) { +// MakeTree creates an AST out of a set of tokens +func MakeTree(tokens *[]Token, file string) Node { out := Node{} - out.Data = Token{Type: 9, Data: "list"} - - currentType := Node{} - currentType.Data = Token{Data: "undefined"} - - for ; tok < max; tok++ { - t0 := (*tokens)[tok] - t1 := (*tokens)[tok+1] - - switch t1.Data { - case ")", "]", "}", ",": - default: - currentType, tok = parseType(tokens, tok, max, true) - t0 = (*tokens)[tok] - t1 = (*tokens)[tok+1] - } - - 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} - } - - typ := currentType - makeParent(&typ, tmp) - makeParent(&out, typ) - - default: - errOut("Error: unexpected token when parsing list, expected user-defined variable or ", 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 -} + out.Data = Token{9, file, 0, 0} -func parseTypeList(tokens *[]Token, tok, max int) (Node, int) { - out := Node{} - out.Data = Token{Type: 9, Data: "list"} - var tmp Node + tmp := Node{} + working := &tmp - tok++ + max := len(*tokens) - for ; tok < max; tok++ { + for tok := 0; tok < max; tok++ { t := (*tokens)[tok] - switch t.Data { - case ")", "]", "}": - return out, tok - case ",": - tok++ - default: - errOut("Error: unexpected token when parsing a list of types", t) - } - - tmp, tok = parseType(tokens, tok, max, true) - out.Sub = append(out.Sub, tmp) - } - - return out, tok -} + case "/;": -func parseVoidType(tokens *[]Token, tok, max int) (Node, int) { - out := Node{} + case ";": - for ; tok < max; tok++ { - //t := (*tokens)[tok] - } + case "/:": - return out, tok -} - -func parseType(tokens *[]Token, tok, max int, param bool) (Node, int) { - out := Node{} - working := &out - - for ; tok < max; tok++ { - t := (*tokens)[tok] - switch t.Type { - case AUGMENT: - if t.Data != "~" && t.Data != "`" { - errOut("Error: unexpected augment token when parsing type", t) - } - working.Data = t - - case KEYTYPE: - if t.Data == "void" { - *working, tok = parseVoidType(tokens, tok, max) - } else { - working.Data = t - } - - return out, tok - - case DEFWORD: - if (*tokens)[tok+1].Data == "(" { - - } - - case KEYWORD: - 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) - } + case ":": default: - errOut("Error: unexpected token when parsing type", t) - } - - makeParent(working, Node{}) - working = &(working.Sub[0]) - } - - return out, tok -} - -func parseValue(tokens *[]Token, tok, max int) (Node, int) { - out := Node{} - - for ; tok < max; tok++ { - t := (*tokens)[tok] - switch t.Type { - case LITERAL: - case DEFWORD: - case DELIMIT: - } - } - - return out, tok -} - -// MakeTree creates an AST out of a set of tokens -func MakeTree(tokens *[]Token, file string) Node { - out := Node{} - out.Data = Token{9, file, 0, 0} - - tmp := Node{} - working := &tmp - - for _, t := range *tokens { - switch t.Type { - case LINESEP: - - case DELIMIT: - + errOut("Unexpected token in file root", t) } tmp = Node{Data: t} |