summaryrefslogtreecommitdiff
path: root/src/tparse
diff options
context:
space:
mode:
authorKyle Gunger <kgunger12@gmail.com>2021-04-30 14:06:58 -0400
committerKyle Gunger <kgunger12@gmail.com>2021-04-30 14:06:58 -0400
commitc625ed1cfe7f7ea4ab2a75a8a0a6a6772f86431c (patch)
tree55aab8a27a6cd3b0a979002afa6899a4bda94b74 /src/tparse
parent60f7c4f7272079e635010e464d8ce3a3a427f97f (diff)
Destroy my own code by using goto
Diffstat (limited to 'src/tparse')
-rw-r--r--src/tparse/resolver.go24
-rw-r--r--src/tparse/tree-list.go45
-rw-r--r--src/tparse/tree-statement.go55
-rw-r--r--src/tparse/tree-value.go130
-rw-r--r--src/tparse/tree.go15
-rw-r--r--src/tparse/type.go5
6 files changed, 181 insertions, 93 deletions
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 {