From c625ed1cfe7f7ea4ab2a75a8a0a6a6772f86431c Mon Sep 17 00:00:00 2001 From: Kyle Gunger Date: Fri, 30 Apr 2021 14:06:58 -0400 Subject: Destroy my own code by using goto --- src/main.go | 2 +- src/tparse/resolver.go | 24 -------- src/tparse/tree-list.go | 45 +-------------- src/tparse/tree-statement.go | 55 ++++++++++++++---- src/tparse/tree-value.go | 130 +++++++++++++++++++++++++++++++++++++++++-- src/tparse/tree.go | 15 +++-- src/tparse/type.go | 5 +- 7 files changed, 182 insertions(+), 94 deletions(-) delete mode 100644 src/tparse/resolver.go (limited to 'src') diff --git a/src/main.go b/src/main.go index c74d0cb..e6efcd9 100644 --- a/src/main.go +++ b/src/main.go @@ -37,7 +37,7 @@ func main() { tokens := tparse.TokenizeFile(*inputFile) tree := tparse.MakeTree(&tokens, *inputFile) - fd.WriteString(fmt.Sprint(tree)) + fd.WriteString(fmt.Sprint(tree) + "\n") fd.Close() } diff --git a/src/tparse/resolver.go b/src/tparse/resolver.go deleted file mode 100644 index 5267887..0000000 --- a/src/tparse/resolver.go +++ /dev/null @@ -1,24 +0,0 @@ -/* - 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 - -//TODO: Everything - -/* - This file is support code to include other files when asked, and represents the most important part of the pre-processor - Maybe we will do this when writing the native compiler though -*/ diff --git a/src/tparse/tree-list.go b/src/tparse/tree-list.go index 78e45a8..843ca9b 100644 --- a/src/tparse/tree-list.go +++ b/src/tparse/tree-list.go @@ -32,7 +32,7 @@ func getClosing(start string) string { // Parse a list of values func parseValueList(tokens *[]Token, tok, max int) (Node, int) { out := Node{} - out.Data = Token{Type: 10, Data: "list"} + out.Data = Token{Type: 10, Data: "value"} var tmp Node c := getClosing((*tokens)[tok].Data) @@ -58,48 +58,9 @@ func parseValueList(tokens *[]Token, tok, max int) (Node, int) { return out, tok } -// Parses a list of definitions -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"} - - c := getClosing((*tokens)[tok].Data) - - tok++ - - for ; tok < max; tok++ { - switch (*tokens)[tok].Data { - case c: - return out, tok - case ",": - tok++ - default: - errOut("Unexpected token when reading parameter definition", (*tokens)[tok]) - } - - t := (*tokens)[tok+1] - - if t.Data != "," && t.Data != c { - currentType, tok = parseType(tokens, tok, max, true) - } - - t = (*tokens)[tok] - - if t.Type != DEFWORD { - errOut("Unexpected token in parameter definition. Expected variable identifier", t) - } - - } - - return out, tok -} - func parseTypeList(tokens *[]Token, tok, max int) (Node, int) { out := Node{} - out.Data = Token{Type: 9, Data: "list"} + out.Data = Token{Type: 10, Data: "type"} var tmp Node c := getClosing((*tokens)[tok].Data) @@ -127,7 +88,7 @@ func parseTypeList(tokens *[]Token, tok, max int) (Node, int) { func parseStatementList(tokens *[]Token, tok, max int) (Node, int) { out := Node{} - out.Data = Token{Type: 9, Data: "list"} + out.Data = Token{Type: 10, Data: "statement"} var tmp Node c := getClosing((*tokens)[tok].Data) diff --git a/src/tparse/tree-statement.go b/src/tparse/tree-statement.go index f6d3452..938e827 100644 --- a/src/tparse/tree-statement.go +++ b/src/tparse/tree-statement.go @@ -18,24 +18,55 @@ package tparse func parseBlock(tokens *[]Token, tok, max int) (Node, int) { out := Node{} - out.Data = Token{Type: 9, Data: "list"} + out.Data = Token{Type: 10, Data: "block"} var tmp Node tok++ - for ; tok < max; tok++ { + for ;tok < max; tok++{ + t := (*tokens)[tok] + + switch t.Type { + case DELIMIT: + if t.Data == "(" { + + } else if t.Data == "(" { + + } else { + goto BREAK + } + case DEFWORD: + case KEYWORD: + case LINESEP: + goto BREAK + } + } + + BREAK: + + for ;tok < max; { t := (*tokens)[tok] switch t.Data { - case ")", "]", "}": + case ";/", ";;", ";:": return out, tok - case ",": - tok++ + case ";": + tmp, tok = parseStatement(tokens, tok, max) + case "/;": + REBLOCK: + + tmp, tok = parseBlock(tokens, tok, max) + + if (*tokens)[tok].Data == ";;" { + out.Sub = append(out.Sub, tmp) + goto REBLOCK + } else if (*tokens)[tok].Data == ";/" { + tok++ + } default: - errOut("Error: unexpected token when parsing a list of types", t) + errOut("Error: unexpected token when parsing a code block", t) } - tmp, tok = parseType(tokens, tok, max, true) out.Sub = append(out.Sub, tmp) } @@ -44,7 +75,7 @@ func parseBlock(tokens *[]Token, tok, max int) (Node, int) { func parseStatement(tokens *[]Token, tok, max int) (Node, int) { out := Node{} - out.Data = Token{Type: 9, Data: "list"} + out.Data = Token{Type: 11, Data: ";"} var tmp Node tok++ @@ -52,10 +83,10 @@ func parseStatement(tokens *[]Token, tok, max int) (Node, int) { for ; tok < max; tok++ { t := (*tokens)[tok] - switch t.Data { - case ")", "]", "}": + switch t.Type { + case LINESEP, DELIMIT: return out, tok - case ",": + case INLNSEP: tok++ default: errOut("Error: unexpected token when parsing a list of types", t) @@ -70,7 +101,7 @@ func parseStatement(tokens *[]Token, tok, max int) (Node, int) { func parseDef(tokens *[]Token, tok, max int) (Node, int) { out := Node{} - out.Data = Token{Type: 9, Data: "list"} + out.Data = Token{Type: 10, Data: "list"} var tmp Node tok++ diff --git a/src/tparse/tree-value.go b/src/tparse/tree-value.go index 1a057d4..d03383e 100644 --- a/src/tparse/tree-value.go +++ b/src/tparse/tree-value.go @@ -16,6 +16,74 @@ package tparse +// Ops order in TNSL +// Cast/Paren > Address > Get > Inc/Dec > Math > Bitwise > Logic + +var ORDER = map[string]int{ + // Address of + "~": 0, + // De-ref + "`": 0, + + // Get + ".": 1, + + // Inc/Dec + "++": 2, + "--": 2, + + // Multiplication + "*": 3, + // Division + "/": 3, + + // Addition + "+": 4, + // Subtraction + "-": 4, + + // Mod + "%": 5, + + // Bitwise and + "&": 6, + // Bitwise or + "|": 6, + // Bitwise xor + "^": 6, + + // Bitwise l-shift + "<<": 6, + // Bitwise r-shift + ">>": 6, + + "!&": 6, + "!|": 6, + "!^": 6, + + // Not (prefix any bool or bitwise) + "!": 6, + + // Boolean and + "&&": 7, + // Boolean or + "||": 7, + // Truthy equals + "==": 7, + + // Greater than + ">": 7, + // Less than + "<": 7, + + "!&&": 7, + "!||": 7, + "!==": 7, + + "!>": 7, + "!<": 7, +} + func parseValue(tokens *[]Token, tok, max int) (Node, int) { out := Node{} @@ -33,9 +101,48 @@ func parseValue(tokens *[]Token, tok, max int) (Node, int) { func parseVoidType(tokens *[]Token, tok, max int) (Node, int) { out := Node{} + working := &out for ; tok < max; tok++ { - //t := (*tokens)[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: + + case DELIMIT: + if t.Data == "{" && tok < max-1 { + if (*tokens)[tok+1].Data == "}" { + working.Data = Token{AUGMENT, "{}", t.Line, t.Char} + tok++ + } else { + errOut("Error: start of list when parsing type (did you mean \"{}\"?)", t) + } + } else if tok >= max-1 { + errOut("Error: unexpected end of file when parsing type", t) + } else { + errOut("Error: unexpected delimeter when parsing type", t) + } + + default: + errOut("Error: unexpected token when parsing type", t) + } + + makeParent(working, Node{}) + working = &(working.Sub[0]) } return out, tok @@ -49,7 +156,7 @@ func parseType(tokens *[]Token, tok, max int, param bool) (Node, int) { t := (*tokens)[tok] switch t.Type { case AUGMENT: - if t.Data != "~" { + if t.Data != "~" && t.Data != "`" { errOut("Error: unexpected augment token when parsing type", t) } working.Data = t @@ -70,22 +177,33 @@ func parseType(tokens *[]Token, tok, max int, param bool) (Node, int) { case KEYWORD: if param && t.Data == "static" { + // Nonstandard keyword in parameter definition errOut("Error: parameter types cannot be static", t) } else if t.Data != "const" && t.Data != "volatile" && t.Data != "static" { + // Nonstandard keyword in variable definition errOut("Error: unexpected keyword when parsing type", t) } working.Data = t case DELIMIT: - if t.Data == "{" { + if t.Data == "{" && tok < max-1 { + // What happens when an array type is defined if (*tokens)[tok+1].Data == "}" { - working.Data = Token{9, "array", t.Line, t.Char} + // Length variable array + working.Data = Token{AUGMENT, "{}", t.Line, t.Char} tok++ + } else if (*tokens)[tok+1].Type == LITERAL { + // Array with constant length } else { - errOut("Error: start of list when parsing type (did you mean {} ?)", t) + // Undefined behaviour + errOut("Error: start of list when parsing type (did you mean \"{}\"?)", t) } + } else if tok >= max-1 { + // End of file with open delimiter after type parsing has begun + errOut("Error: unexpected end of file when parsing type", t) } else { - errOut("Error: start of list when parsing type", t) + // Other delimiter than {} used in variable definition + errOut("Error: unexpected delimeter when parsing type", t) } default: diff --git a/src/tparse/tree.go b/src/tparse/tree.go index 0b7baf4..9e9e554 100644 --- a/src/tparse/tree.go +++ b/src/tparse/tree.go @@ -18,7 +18,8 @@ package tparse import "fmt" -// ID 9 = ast thing +// ID 9 = ast root +// ID 10 = ast list func errOut(message string, token Token) { fmt.Println(message) @@ -32,7 +33,6 @@ func MakeTree(tokens *[]Token, file string) Node { out.Data = Token{9, file, 0, 0} tmp := Node{} - working := &tmp max := len(*tokens) @@ -40,19 +40,18 @@ func MakeTree(tokens *[]Token, file string) Node { t := (*tokens)[tok] switch t.Data { case "/;": - + tmp, tok = parseBlock(tokens, tok, max) case ";": - + tmp, tok = parseStatement(tokens, tok, max) case "/:": - + tmp = Node{} case ":": - + tmp = Node{} default: errOut("Unexpected token in file root", t) } - tmp = Node{Data: t} - working.Sub = append(working.Sub, tmp) + out.Sub = append(out.Sub, tmp) } return out diff --git a/src/tparse/type.go b/src/tparse/type.go index 70d8776..73bb94d 100644 --- a/src/tparse/type.go +++ b/src/tparse/type.go @@ -50,8 +50,11 @@ var PREWORDS = []string{ "extern", "size", "align", + "origin", + "rootfile", "if", "else", + "abi", //"mark", } @@ -128,7 +131,7 @@ var RESWORD = map[string]int{ "module": KEYWORD, "export": KEYWORD, - "_": KEYWORD, + "drop": KEYWORD, } func checkResWord(s string) int { -- cgit v1.2.3