From ea5ef2fe245c09b35c783977928d6e995110cfb4 Mon Sep 17 00:00:00 2001 From: Kyle Gunger Date: Mon, 30 Aug 2021 19:07:26 -0400 Subject: Scrap old spec, add initial value parsing --- src/tparse/tree-preproc.go | 49 ++++++++++++++++ src/tparse/tree-value.go | 138 ++++++++++++++++++++++++++++++++++++++++----- src/tparse/tree.go | 4 +- src/tparse/type.go | 5 +- 4 files changed, 179 insertions(+), 17 deletions(-) create mode 100644 src/tparse/tree-preproc.go (limited to 'src') diff --git a/src/tparse/tree-preproc.go b/src/tparse/tree-preproc.go new file mode 100644 index 0000000..d0f6637 --- /dev/null +++ b/src/tparse/tree-preproc.go @@ -0,0 +1,49 @@ +/* + 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 parsePreBlock (tokens *[]Token, tok, max int) (Node, int) { + out := Node{IsBlock: true} + out.Data = Token{Type: 11, Data: (*tokens)[tok].Data} + + tok++ + + for ; tok < max; tok++ { + t := (*tokens)[tok] + + if t.Data == ":/" { + break + } + + tmp := Node{Data: t, IsBlock: false} + out.Sub = append(out.Sub, tmp) + } + + return out, tok +} + +func parsePre (tokens *[]Token, tok, max int) (Node, int) { + out := Node{IsBlock: false} + out.Data = Token{Type: 11, Data: (*tokens)[tok].Data} + + tok++ + + tmp := Node{Data: (*tokens)[tok], IsBlock: false} + out.Sub = append(out.Sub, tmp) + + return out, tok +} \ No newline at end of file diff --git a/src/tparse/tree-value.go b/src/tparse/tree-value.go index d03383e..7880a8b 100644 --- a/src/tparse/tree-value.go +++ b/src/tparse/tree-value.go @@ -19,18 +19,20 @@ package tparse // Ops order in TNSL // Cast/Paren > Address > Get > Inc/Dec > Math > Bitwise > Logic -var ORDER = map[string]int{ - // Address of +var UNARY = map[string]int { "~": 0, - // De-ref "`": 0, + "++": 2, + "--": 2, + "!": 6, +} + +var ORDER = map[string]int{ // Get ".": 1, - // Inc/Dec - "++": 2, - "--": 2, + "is": 2, // Multiplication "*": 3, @@ -61,9 +63,6 @@ var ORDER = map[string]int{ "!|": 6, "!^": 6, - // Not (prefix any bool or bitwise) - "!": 6, - // Boolean and "&&": 7, // Boolean or @@ -82,23 +81,133 @@ var ORDER = map[string]int{ "!>": 7, "!<": 7, + + // Assignement + "=": 8, +} + +// Works? Please test. +func parseUnaryOps(tokens *[]Token, tok, max int) (Node) { + out := Node{Data: Token{Type: 10, Data: "value"}, IsBlock: false} + val := false + + // Pre-value op scan + for ; tok < max && !val; tok++ { + t := (*tokens)[tok] + switch t.Type { + case DEFWORD: + fallthrough + case LITERAL: + out.Sub = append(out.Sub, Node{Data: t, IsBlock: false}) + val = true + case AUGMENT: + _, prs := UNARY[t.Data] + if !prs { + errOut("Parser bug! Operator failed to load into AST.", t) + } else { + out.Sub = append(out.Sub, Node{Data: t, IsBlock: false}) + } + default: + errOut("Unexpected token in value declaration", t) + } + } + + // Sanity check: make sure there's actually a value here + if !val { + errOut("Expected to find value, but there wasn't one", (*tokens)[max]) + } + + // Post-value op scan + for ; tok < max; tok++ { + t := (*tokens)[tok] + switch t.Type { + case DELIMIT: + var tmp Node + switch t.Data { + case "(": // Function call + //TODO: parse list of values here + case "[": // Typecasting + tmp, tok = parseType(tokens, tok, max, false) + out.Sub = append(out.Sub, tmp) + case "{": // Array indexing + tmp = Node{Data: Token{Type: 10, Data: "index"}} + var tmp2 Node + tmp2, tok = parseValue(tokens, tok + 1, max) + tmp.Sub = append(tmp.Sub, tmp2) + out.Sub = append(out.Sub, tmp) + default: + errOut("Unexpected delimiter when parsing value", t) + } + case AUGMENT: + _, prs := UNARY[t.Data] + if !prs { + errOut("Parser bug! Operator failed to load into AST.", t) + } else { + out.Sub = append(out.Sub, Node{Data: t, IsBlock: false}) + } + default: + errOut("Unexpected token in value declaration", t) + } + } + + return out +} + +// Works? Please test. +func parseBinaryOp(tokens *[]Token, tok, max int) (Node) { + out := Node{IsBlock: false} + first := tok + var high, highOrder, bincount int = first, 8, 0 + + // Find first high-order op + for ; tok < max; tok++ { + t := (*tokens)[tok] + if t.Type == AUGMENT { + order, prs := ORDER[t.Data] + if !prs { + continue + } else if order > highOrder { + high, highOrder = tok, order + } + // TODO: Add in case for the "is" operator + bincount++ + } + } + + out.Data = (*tokens)[high] + + if bincount == 0 { + // No binops means we have a value to parse. Parse all unary ops around it. + return parseUnaryOps(tokens, first, max) + } else { + // Recursive split to lower order operations + out.Sub = append(out.Sub, parseBinaryOp(tokens, first, high)) + out.Sub = append(out.Sub, parseBinaryOp(tokens, high + 1, max)) + } + + return out } +// TODO: fix this func parseValue(tokens *[]Token, tok, max int) (Node, int) { - out := Node{} + first := tok + for ; tok < max; tok++ { t := (*tokens)[tok] switch t.Type { - case LITERAL: - case DEFWORD: + case LINESEP: + case INLNSEP: case DELIMIT: + case AUGMENT: + case LITERAL: } } - return out, tok + return parseBinaryOp(tokens, first, tok), tok } +// TODO: make sure this actually works func parseVoidType(tokens *[]Token, tok, max int) (Node, int) { out := Node{} working := &out @@ -148,8 +257,9 @@ func parseVoidType(tokens *[]Token, tok, max int) (Node, int) { return out, tok } +// TODO: make sure this actually works func parseType(tokens *[]Token, tok, max int, param bool) (Node, int) { - out := Node{} + out := Node{Data: Token{Type: 10, Data: "type"}} working := &out for ; tok < max; tok++ { diff --git a/src/tparse/tree.go b/src/tparse/tree.go index 08c94bf..af3e184 100644 --- a/src/tparse/tree.go +++ b/src/tparse/tree.go @@ -44,9 +44,9 @@ func MakeTree(tokens *[]Token, file string) Node { case ";": tmp, tok = parseStatement(tokens, tok, max) case "/:": - tmp = Node{} + tmp, tok = parsePreBlock(tokens, tok + 1, max) case ":": - tmp = Node{} + tmp, tok = parsePre(tokens, tok + 1, max) default: errOut("Unexpected token in file root", t) } diff --git a/src/tparse/type.go b/src/tparse/type.go index b860f02..7113c0b 100644 --- a/src/tparse/type.go +++ b/src/tparse/type.go @@ -56,6 +56,7 @@ var PREWORDS = []string{ "else", "abi", //"mark", + "using", } func checkPreWord(s string) int { @@ -92,7 +93,7 @@ var RESWORD = map[string]int{ "struct": KEYWORD, "interface": KEYWORD, "enum": KEYWORD, - "is": KEYWORD, + "is": AUGMENT, "extends": KEYWORD, "loop": KEYWORD, @@ -126,6 +127,8 @@ var RESWORD = map[string]int{ "true": LITERAL, "false": LITERAL, + "alloc": KEYWORD, + "calloc": KEYWORD, "delete": KEYWORD, "module": KEYWORD, -- cgit v1.2.3