From be0f69df2c0fc4bc8f64e8d51aa06b4b56f3401d Mon Sep 17 00:00:00 2001 From: Kyle Gunger Date: Sat, 30 Oct 2021 01:54:02 -0400 Subject: [AST] Fixes for some statements in blocks --- src/tparse/token.go | 3 --- src/tparse/tokenize.go | 2 +- src/tparse/tree-list.go | 63 ++++++++++++++++++++++++++------------------ src/tparse/tree-statement.go | 28 +++++++++++--------- src/tparse/tree-value.go | 31 +++++++++++++++++----- src/tparse/tree.go | 11 +++++++- 6 files changed, 89 insertions(+), 49 deletions(-) (limited to 'src/tparse') diff --git a/src/tparse/token.go b/src/tparse/token.go index 02502eb..6c84c72 100644 --- a/src/tparse/token.go +++ b/src/tparse/token.go @@ -29,9 +29,6 @@ type Node struct { Data Token IsBlock bool - BlockQs []Token - BlockIn []Node - BlockOut []Node Sub []Node } diff --git a/src/tparse/tokenize.go b/src/tparse/tokenize.go index 11531b5..2231907 100644 --- a/src/tparse/tokenize.go +++ b/src/tparse/tokenize.go @@ -33,7 +33,7 @@ func numericLiteral(r *bufio.Reader, line int, char *int) Token { b := strings.Builder{} for ; err == nil; run, _, err = r.ReadRune() { - if (run == '.' || run == ',') && !decimal { + if (run == '.') && !decimal { decimal = true } else if !unicode.IsNumber(run) { break diff --git a/src/tparse/tree-list.go b/src/tparse/tree-list.go index 0a98e8c..9cfd55f 100644 --- a/src/tparse/tree-list.go +++ b/src/tparse/tree-list.go @@ -31,7 +31,7 @@ func getClosing(start string) string { // Parse a list of values func parseValueList(tokens *[]Token, tok, max int) (Node, int) { - out := Node{Data: Token{Type: 10, Data: "list"}, IsBlock: false} + out := Node{Data: Token{Type: 10, Data: "vlist"}, IsBlock: false} var tmp Node tmp, tok = parseValue(tokens, tok, max) @@ -45,7 +45,7 @@ func parseValueList(tokens *[]Token, tok, max int) (Node, int) { case LINESEP: fallthrough case DELIMIT: - return out, tok + 1 + return out, tok case INLNSEP: tok++ default: @@ -61,28 +61,40 @@ func parseValueList(tokens *[]Token, tok, max int) (Node, int) { // Parse list of parameters func parseParamList(tokens *[]Token, tok, max int) (Node, int) { - out := Node{} - out.Data = Token{Type: 10, Data: "param"} + out := Node{Data: Token{Type: 10, Data: "plist"}, IsBlock: false} var tmp Node - c := getClosing((*tokens)[tok].Data) - - tok++ + if isTypeThenValue(tokens, tok, max) { + tmp, tok = parseType(tokens, tok, max, true) + out.Sub = append(out.Sub, tmp) + tmp, tok = parseValue(tokens, tok, max) + out.Sub = append(out.Sub, tmp) + } else { + errOut("Error: no initial type in parameter list", (*tokens)[tok]) + } + + for ; tok < max; { - for ; tok < max; tok++ { t := (*tokens)[tok] - - switch t.Data { - case c: + + switch t.Type { + case LINESEP: + fallthrough + case DELIMIT: return out, tok - case ",": + case INLNSEP: 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) + if isTypeThenValue(tokens, tok, max) { + tmp, tok = parseType(tokens, tok, max, true) + out.Sub = append(out.Sub, tmp) + } else { + tmp, tok = parseValue(tokens, tok, max) + out.Sub = append(out.Sub, tmp) + } } return out, tok @@ -90,24 +102,25 @@ func parseParamList(tokens *[]Token, tok, max int) (Node, int) { // Parse a list of types func parseTypeList(tokens *[]Token, tok, max int) (Node, int) { - out := Node{} - out.Data = Token{Type: 10, Data: "type"} + out := Node{Data: Token{Type: 10, Data: "tlist"}, IsBlock: false} var tmp Node - c := getClosing((*tokens)[tok].Data) - - tok++ + tmp, tok = parseType(tokens, tok, max, true) + out.Sub = append(out.Sub, tmp) + + for ; tok < max; { - for ; tok < max; tok++ { t := (*tokens)[tok] - - switch t.Data { - case c: + + switch t.Type { + case LINESEP: + fallthrough + case DELIMIT: return out, tok - case ",": + case INLNSEP: tok++ default: - errOut("Error: unexpected token when parsing a list of types", t) + errOut("Error: unexpected token when parsing a list of values", t) } tmp, tok = parseType(tokens, tok, max, true) diff --git a/src/tparse/tree-statement.go b/src/tparse/tree-statement.go index ed10b42..9280253 100644 --- a/src/tparse/tree-statement.go +++ b/src/tparse/tree-statement.go @@ -20,9 +20,8 @@ package tparse func parseBlock(tokens *[]Token, tok, max int) (Node, int) { out, tmp, def, name := Node{}, Node{}, Node{}, false out.Data = Token{Type: 10, Data: "block"} - def.Data = Token{Type: 10, Data: "blockdef"} - - tok++ + out.IsBlock = true + def.Data = Token{Type: 10, Data: "bdef"} for ;tok < max; tok++{ t := (*tokens)[tok] @@ -30,10 +29,10 @@ func parseBlock(tokens *[]Token, tok, max int) (Node, int) { switch t.Type { case DELIMIT: if t.Data == "(" { - tmp, tok = parseValueList(tokens, tok, max) + tmp, tok = parseParamList(tokens, tok + 1, max) def.Sub = append(def.Sub, tmp) } else if t.Data == "[" { - tmp, tok = parseTypeList(tokens, tok, max) + tmp, tok = parseTypeList(tokens, tok + 1, max) def.Sub = append(def.Sub, tmp) } else { goto BREAK @@ -53,12 +52,18 @@ func parseBlock(tokens *[]Token, tok, max int) (Node, int) { case "else": if (*tokens)[tok+1].Data == "if" { tmp.Data = Token{KEYWORD, "elif", t.Line, t.Char} + def.Sub = append(def.Sub, tmp) tok++ - name = true continue } case "if", "match", "case", "loop": + name = true + fallthrough case "export", "inline", "raw", "override": + tmp.Data = t + def.Sub = append(def.Sub, tmp) + default: + errOut("Unexpected keyword in block definition.", t) } case LINESEP: goto BREAK @@ -76,11 +81,12 @@ func parseBlock(tokens *[]Token, tok, max int) (Node, int) { case ";/", ";;", ";:": return out, tok case ";": - tmp, tok = parseStatement(tokens, tok, max) + + tmp, tok = parseStatement(tokens, tok + 1, max) case "/;": REBLOCK: - tmp, tok = parseBlock(tokens, tok, max) + tmp, tok = parseBlock(tokens, tok + 1, max) if (*tokens)[tok].Data == ";;" { out.Sub = append(out.Sub, tmp) @@ -162,7 +168,7 @@ func keywordStatement(tokens *[]Token, tok, max int) (Node, int) { errOut("Could not find struct member list", (*tokens)[tok]) } - tmp, tok = parseValueList(tokens, tok, max) + tmp, tok = parseParamList(tokens, tok, max) case "goto", "label": if (*tokens)[tok].Type != DEFWORD { @@ -193,11 +199,9 @@ func keywordStatement(tokens *[]Token, tok, max int) (Node, int) { // Should work, but none of this is tested. func parseDef(tokens *[]Token, tok, max int) (Node, int) { - out := Node{} - out.Data = Token{} + out := Node{Data: Token{11, "vdef", 0, 0}} var tmp Node - tmp, tok = parseType(tokens, tok, max, false) out.Sub = append(out.Sub, tmp) tmp, tok = parseValueList(tokens, tok, max) diff --git a/src/tparse/tree-value.go b/src/tparse/tree-value.go index d7d01ec..b9796c8 100644 --- a/src/tparse/tree-value.go +++ b/src/tparse/tree-value.go @@ -221,18 +221,21 @@ func parseBinaryOp(tokens *[]Token, tok, max int) (Node) { // Works? Please test. func parseValue(tokens *[]Token, tok, max int) (Node, int) { first := tok - var curl, brak, parn int = 0, 0, 0 + var curl, brak, parn, block int = 0, 0, 0, 0 for ; tok < max; tok++ { t := (*tokens)[tok] switch t.Type { case LINESEP: + if block > 0 { + continue + } if curl > 0 || brak > 0 || parn > 0 { errOut("Encountered end of statement before all delimiter pairs were closed while looking for the end of a value.", t) } goto PARSEBIN case INLNSEP: - if curl > 0 || brak > 0 || parn > 0 { + if curl > 0 || brak > 0 || parn > 0 || block > 0 { continue } goto PARSEBIN @@ -251,6 +254,24 @@ func parseValue(tokens *[]Token, tok, max int) (Node, int) { brak-- case ")": parn-- + + case "/;": + block++ + case ";/": + if block > 0 { + block-- + } + fallthrough + case ";;": + if block > 1 { + continue + } else if block == 1 { + errOut("Error: redefinition of a block from a block as a value is not permitted.", t) + } + if curl > 0 || brak > 0 || parn > 0 { + errOut("Delimeter pairs not closed before end of value", t) + } + goto PARSEBIN } // TODO: Support blocks as values @@ -316,11 +337,9 @@ func parseTypeParams(tokens *[]Token, tok, max int) (Node, int) { func parseType(tokens *[]Token, tok, max int, param bool) (Node, int) { out := Node{Data: Token{Type: 10, Data: "type"}, IsBlock: false} - - for ; tok < max; tok++ { t := (*tokens)[tok] - + var tmp Node switch t.Type { case AUGMENT: @@ -372,7 +391,6 @@ func parseType(tokens *[]Token, tok, max int, param bool) (Node, int) { } } else if t.Data == ")" || t.Data == "]" || t.Data == "}"{ // End of type - tok-- goto TYPEDONE } else { errOut("Error: unexpected delimeter when parsing type", t) @@ -383,7 +401,6 @@ func parseType(tokens *[]Token, tok, max int, param bool) (Node, int) { } default: - tok-- goto TYPEDONE } diff --git a/src/tparse/tree.go b/src/tparse/tree.go index 00e75fb..03d2a3d 100644 --- a/src/tparse/tree.go +++ b/src/tparse/tree.go @@ -46,8 +46,17 @@ func MakeTree(tokens *[]Token, file string) Node { for tok := 0; tok < max; { t := (*tokens)[tok] switch t.Data { - case "/;": + case "/;", ";;", ":;": + REBLOCK: + tmp, tok = parseBlock(tokens, tok + 1, max) + + if (*tokens)[tok].Data == ";;" { + out.Sub = append(out.Sub, tmp) + goto REBLOCK + } else if (*tokens)[tok].Data == ";/" { + tok++ + } case ";": tmp, tok = parseStatement(tokens, tok + 1, max) case "/:": -- cgit v1.2.3