From 3395cd7dc356b61fe48ee9d755eef8a7b19ee9f1 Mon Sep 17 00:00:00 2001 From: Kyle Gunger Date: Fri, 29 Oct 2021 20:06:51 -0400 Subject: [AST] Statement parsing (incomplete) Still need to figure out a check for a type followed by a value --- src/tparse/tree-statement.go | 146 ++++++++++++++++++++++++++++++++----------- src/tparse/tree-value.go | 13 ++-- 2 files changed, 117 insertions(+), 42 deletions(-) (limited to 'src') diff --git a/src/tparse/tree-statement.go b/src/tparse/tree-statement.go index 167cee2..bb8bde2 100644 --- a/src/tparse/tree-statement.go +++ b/src/tparse/tree-statement.go @@ -17,32 +17,48 @@ package tparse func parseBlock(tokens *[]Token, tok, max int) (Node, int) { - out := Node{} + out, tmp, def, name := Node{}, Node{}, Node{}, false out.Data = Token{Type: 10, Data: "block"} - var tmp Node + def.Data = Token{Type: 10, Data: "blockdef"} tok++ - def := Node{} - def.Data = Token{Type: 10, Data: "blockdef"} - for ;tok < max; tok++{ t := (*tokens)[tok] - + tmp = Node{} switch t.Type { case DELIMIT: if t.Data == "(" { - tmp, tok = parseParamList(tokens, tok, max) - def.Sub = append(out.Sub, tmp) + tmp, tok = parseValueList(tokens, tok, max) + def.Sub = append(def.Sub, tmp) } else if t.Data == "[" { tmp, tok = parseTypeList(tokens, tok, max) - def.Sub = append(out.Sub, tmp) + def.Sub = append(def.Sub, tmp) } else { goto BREAK } case DEFWORD: - + if name { + errOut("Unexpected defword, the block has already been given a name or keyword.", t) + } + tmp.Data = t + def.Sub = append(def.Sub, tmp) + name = true case KEYWORD: + if name { + errOut("Unexpected keyword, the block has already been given a name or keyword.", t) + } + switch t.Data { + case "else": + if (*tokens)[tok+1].Data == "if" { + tmp.Data = Token{KEYWORD, "elif", t.Line, t.Char} + tok++ + name = true + continue + } + case "if", "match", "case", "loop": + case "export", "inline", "raw", "override": + } case LINESEP: goto BREAK } @@ -86,49 +102,103 @@ func parseStatement(tokens *[]Token, tok, max int) (Node, int) { out.Data = Token{Type: 11, Data: ";"} var tmp Node - tok++ - - for ; tok < max; tok++ { - t := (*tokens)[tok] - - switch t.Type { - case LINESEP, DELIMIT: - return out, tok - case INLNSEP: - tok++ - default: - errOut("Error: unexpected token when parsing a list of types", t) + // Check for keyword, definition, then if none of those apply, assume it's a value. + if (*tokens)[tok].Type == KEYWORD { + tmp, tok = keywordStatement(tokens, tok, max) + out.Sub = append(out.Sub, tmp) + } else { + // do check for definition + if false { + // if not, parse a value + tmp, tok = parseDefinition(tokens, tok, max) + } else { + // if not, parse a value + tmp, tok = parseValue(tokens, tok, max) } - - tmp, tok = parseType(tokens, tok, max, true) out.Sub = append(out.Sub, tmp) } return out, tok } -func parseDef(tokens *[]Token, tok, max int) (Node, int) { +// Works? Please test. +func keywordStatement(tokens *[]Token, tok, max int) (Node, int) { out := Node{} - out.Data = Token{Type: 10, Data: "list"} + out.Data = (*tokens)[tok] + out.IsBlock = false var tmp Node + tmp.IsBlock = false - tok++ + if tok + 1 < max { + tok++ + } else { + return out, max + } - for ; tok < max; tok++ { - t := (*tokens)[tok] + switch out.Data.Data { + case "raw": + // Something, something... code. + if (*tokens)[tok].Data != "struct" { + errOut("Unexpected use of raw operator in a statement", out.Data) + } + tok++ + fallthrough + case "struct": + // Check for defword, (), and {} then dip + if (*tokens)[tok].Type != DEFWORD { + errOut("Expected defword after struct keyword.", (*tokens)[tok]) + } + tmp.Data = (*tokens)[tok] + out.Sub = append(out.Sub, tmp) + tok++ + if (*tokens)[tok].Data == "(" { + tmp, tok = parseValueList(tokens, tok, max) + out.Sub = append(out.Sub, tmp) + } - switch t.Data { - case ")", "]", "}": - return out, tok - case ",": - tok++ - default: - errOut("Error: unexpected token when parsing a list of types", t) + if (*tokens)[tok].Data != "{" { + errOut("Could not find struct member list", (*tokens)[tok]) } - tmp, tok = parseType(tokens, tok, max, true) - out.Sub = append(out.Sub, tmp) + tmp, tok = parseValueList(tokens, tok, max) + + case "goto", "label": + if (*tokens)[tok].Type != DEFWORD { + errOut("Expected defword after goto or label keyword.", out.Data) + } + tmp.Data = (*tokens)[tok] + tok++ + // Check for a defword and dip + case "continue", "break": + if (*tokens)[tok].Type != LITERAL { + return out, tok + } + tmp.Data = (*tokens)[tok] + tok++ + // Check for a numerical value and dip + case "alloc", "salloc": + // Parse value list + tmp, tok = parseValueList(tokens, tok, max) + case "delete": + // Parse value list + tmp, tok = parseValueList(tokens, tok, max) } + out.Sub = append(out.Sub, tmp) + + return out, tok +} + +func parseDef(tokens *[]Token, tok, max int) (Node, int) { + out := Node{} + out.Data = Token{} + var tmp Node + + + tmp, tok = parseType(tokens, tok, max, false) + out.Sub = append(out.Sub, tmp) + tmp, tok = parseValueList(tokens, tok, max) + out.Sub = append(out.Sub, tmp) + return out, tok } diff --git a/src/tparse/tree-value.go b/src/tparse/tree-value.go index ab73230..af547a5 100644 --- a/src/tparse/tree-value.go +++ b/src/tparse/tree-value.go @@ -314,7 +314,7 @@ func parseTypeParams(tokens *[]Token, tok, max int) (Node, int) { // TODO: make sure this actually works func parseType(tokens *[]Token, tok, max int, param bool) (Node, int) { - out := Node{Data: Token{Type: 10, Data: "type"}} + out := Node{Data: Token{Type: 10, Data: "type"}, IsBlock: false} for ; tok < max; tok++ { t := (*tokens)[tok] @@ -365,6 +365,10 @@ func parseType(tokens *[]Token, tok, max int, param bool) (Node, int) { tmp2, tok = parseValue(tokens, tok + 1, max) tmp.Sub = append(tmp.Sub, tmp2) } + } else if t.Data == ")" || t.Data == "]" || t.Data == "}"{ + // End of type + tok-- + goto TYPEDONE } else { errOut("Error: unexpected delimeter when parsing type", t) } @@ -374,13 +378,14 @@ func parseType(tokens *[]Token, tok, max int, param bool) (Node, int) { } default: - errOut("Error: unexpected token when parsing type", t) + tok-- + goto TYPEDONE } out.Sub = append(out.Sub, tmp) } - - errOut("End of token list when trying to parse type", (*tokens)[max - 1]) + + TYPEDONE: return out, tok } -- cgit v1.2.3