diff options
| -rw-r--r-- | src/tparse/tree-list.go | 124 | ||||
| -rw-r--r-- | src/tparse/tree-statement.go | 17 | ||||
| -rw-r--r-- | src/tparse/tree-value.go | 100 | ||||
| -rw-r--r-- | src/tparse/tree.go | 205 | 
4 files changed, 253 insertions, 193 deletions
| diff --git a/src/tparse/tree-list.go b/src/tparse/tree-list.go new file mode 100644 index 0000000..70f5fff --- /dev/null +++ b/src/tparse/tree-list.go @@ -0,0 +1,124 @@ +/* +   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 + +// Parse a list of values +func parseValueList(tokens *[]Token, tok, max int) (Node, int) { +	out := Node{} +	out.Data = Token{Type: 10, Data: "list"} +	var tmp Node + +	tok++ + +	for ; tok < max; tok++ { +		t := (*tokens)[tok] + +		switch t.Data { +		case ")", "]", "}": +			return out, tok +		case ",": +			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) +	} + +	return out, tok +} + +// Parses a list of things +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"} + +	for ; tok < max; tok++ { +		t0 := (*tokens)[tok] +		t1 := (*tokens)[tok+1] + +		switch t1.Data { +		case ")", "]", "}", ",": +		default: +			currentType, tok = parseType(tokens, tok, max, true) +			t0 = (*tokens)[tok] +			t1 = (*tokens)[tok+1] +		} + +		switch t0.Type { + +		case DEFWORD: +			var tmp Node +			if currentType.Data.Data == "undefined" { +				errOut("Error: expected type before first parameter", t0) +			} else if currentType.Data.Data == "type" { +				tmp, tok = parseType(tokens, tok, max, true) +			} else { +				tmp = Node{Data: t0} +			} + +			typ := currentType +			makeParent(&typ, tmp) +			makeParent(&out, typ) + +		default: +			errOut("Error: unexpected token when parsing list, expected user-defined variable or ", t0) +		} + +		switch t1.Data { +		case ")", "]", "}": +			return out, tok +		case ",": +		default: +			errOut("Error: unexpected token when parsing list, expected ',' or end of list", t1) +		} + +		tok++ +	} + +	return out, tok +} + +func parseTypeList(tokens *[]Token, tok, max int) (Node, int) { +	out := Node{} +	out.Data = Token{Type: 9, Data: "list"} +	var tmp Node + +	tok++ + +	for ; tok < max; tok++ { +		t := (*tokens)[tok] + +		switch t.Data { +		case ")", "]", "}": +			return out, tok +		case ",": +			tok++ +		default: +			errOut("Error: unexpected token when parsing a list of types", t) +		} + +		tmp, tok = parseType(tokens, tok, max, true) +		out.Sub = append(out.Sub, tmp) +	} + +	return out, tok +} diff --git a/src/tparse/tree-statement.go b/src/tparse/tree-statement.go new file mode 100644 index 0000000..9d0b0d6 --- /dev/null +++ b/src/tparse/tree-statement.go @@ -0,0 +1,17 @@ +/* +   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 diff --git a/src/tparse/tree-value.go b/src/tparse/tree-value.go new file mode 100644 index 0000000..1a057d4 --- /dev/null +++ b/src/tparse/tree-value.go @@ -0,0 +1,100 @@ +/* +   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 parseValue(tokens *[]Token, tok, max int) (Node, int) { +	out := Node{} + +	for ; tok < max; tok++ { +		t := (*tokens)[tok] +		switch t.Type { +		case LITERAL: +		case DEFWORD: +		case DELIMIT: +		} +	} + +	return out, tok +} + +func parseVoidType(tokens *[]Token, tok, max int) (Node, int) { +	out := Node{} + +	for ; tok < max; tok++ { +		//t := (*tokens)[tok] +	} + +	return out, tok +} + +func parseType(tokens *[]Token, tok, max int, param bool) (Node, int) { +	out := Node{} +	working := &out + +	for ; tok < max; tok++ { +		t := (*tokens)[tok] +		switch t.Type { +		case AUGMENT: +			if 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: +			if (*tokens)[tok+1].Data == "(" { + +			} + +		case KEYWORD: +			if param && t.Data == "static" { +				errOut("Error: parameter types cannot be static", t) +			} else if t.Data != "const" && t.Data != "volatile" && t.Data != "static" { +				errOut("Error: unexpected keyword when parsing type", t) +			} +			working.Data = t + +		case DELIMIT: +			if t.Data == "{" { +				if (*tokens)[tok+1].Data == "}" { +					working.Data = Token{9, "array", t.Line, t.Char} +					tok++ +				} else { +					errOut("Error: start of list when parsing type (did you mean {} ?)", t) +				} +			} else { +				errOut("Error: start of list when parsing type", t) +			} + +		default: +			errOut("Error: unexpected token when parsing type", t) +		} + +		makeParent(working, Node{}) +		working = &(working.Sub[0]) +	} + +	return out, tok +} diff --git a/src/tparse/tree.go b/src/tparse/tree.go index ed19e6d..0b7baf4 100644 --- a/src/tparse/tree.go +++ b/src/tparse/tree.go @@ -26,210 +26,29 @@ func errOut(message string, token Token) {  	panic("AST Error")  } -// Parse a list of values -func parseValueList(tokens *[]Token, tok, max int) (Node, int) { -	out := Node{} -	out.Data = Token{Type: 10, Data: "list"} -	var tmp Node - -	tok++ - -	for ; tok < max; tok++ { -		t := (*tokens)[tok] - -		switch t.Data { -		case ")", "]", "}": -			return out, tok -		case ",": -			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) -	} - -	return out, tok -} - -// Parses a list of things -func parseDefList(tokens *[]Token, tok, max int) (Node, int) { +// MakeTree creates an AST out of a set of tokens +func MakeTree(tokens *[]Token, file string) Node {  	out := Node{} -	out.Data = Token{Type: 9, Data: "list"} - -	currentType := Node{} -	currentType.Data = Token{Data: "undefined"} - -	for ; tok < max; tok++ { -		t0 := (*tokens)[tok] -		t1 := (*tokens)[tok+1] - -		switch t1.Data { -		case ")", "]", "}", ",": -		default: -			currentType, tok = parseType(tokens, tok, max, true) -			t0 = (*tokens)[tok] -			t1 = (*tokens)[tok+1] -		} - -		switch t0.Type { - -		case DEFWORD: -			var tmp Node -			if currentType.Data.Data == "undefined" { -				errOut("Error: expected type before first parameter", t0) -			} else if currentType.Data.Data == "type" { -				tmp, tok = parseType(tokens, tok, max, true) -			} else { -				tmp = Node{Data: t0} -			} - -			typ := currentType -			makeParent(&typ, tmp) -			makeParent(&out, typ) - -		default: -			errOut("Error: unexpected token when parsing list, expected user-defined variable or ", t0) -		} - -		switch t1.Data { -		case ")", "]", "}": -			return out, tok -		case ",": -		default: -			errOut("Error: unexpected token when parsing list, expected ',' or end of list", t1) -		} - -		tok++ -	} - -	return out, tok -} +	out.Data = Token{9, file, 0, 0} -func parseTypeList(tokens *[]Token, tok, max int) (Node, int) { -	out := Node{} -	out.Data = Token{Type: 9, Data: "list"} -	var tmp Node +	tmp := Node{} +	working := &tmp -	tok++ +	max := len(*tokens) -	for ; tok < max; tok++ { +	for tok := 0; tok < max; tok++ {  		t := (*tokens)[tok] -  		switch t.Data { -		case ")", "]", "}": -			return out, tok -		case ",": -			tok++ -		default: -			errOut("Error: unexpected token when parsing a list of types", t) -		} +		case "/;": -		tmp, tok = parseType(tokens, tok, max, true) -		out.Sub = append(out.Sub, tmp) -	} +		case ";": -	return out, tok -} - -func parseVoidType(tokens *[]Token, tok, max int) (Node, int) { -	out := Node{} - -	for ; tok < max; tok++ { -		//t := (*tokens)[tok] -	} - -	return out, tok -} - -func parseType(tokens *[]Token, tok, max int, param bool) (Node, int) { -	out := Node{} -	working := &out - -	for ; tok < max; 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: -			if (*tokens)[tok+1].Data == "(" { - -			} +		case "/:": -		case KEYWORD: -			if param && t.Data == "static" { -				errOut("Error: parameter types cannot be static", t) -			} else if t.Data != "const" && t.Data != "volatile" && t.Data != "static" { -				errOut("Error: unexpected keyword when parsing type", t) -			} -			working.Data = t - -		case DELIMIT: -			if t.Data == "{" { -				if (*tokens)[tok+1].Data == "}" { -					working.Data = Token{9, "array", t.Line, t.Char} -					tok++ -				} else { -					errOut("Error: start of list when parsing type (did you mean {} ?)", t) -				} -			} else { -				errOut("Error: start of list when parsing type", t) -			} +		case ":":  		default: -			errOut("Error: unexpected token when parsing type", t) -		} - -		makeParent(working, Node{}) -		working = &(working.Sub[0]) -	} - -	return out, tok -} - -func parseValue(tokens *[]Token, tok, max int) (Node, int) { -	out := Node{} - -	for ; tok < max; tok++ { -		t := (*tokens)[tok] -		switch t.Type { -		case LITERAL: -		case DEFWORD: -		case DELIMIT: -		} -	} - -	return out, tok -} - -// MakeTree creates an AST out of a set of tokens -func MakeTree(tokens *[]Token, file string) Node { -	out := Node{} -	out.Data = Token{9, file, 0, 0} - -	tmp := Node{} -	working := &tmp - -	for _, t := range *tokens { -		switch t.Type { -		case LINESEP: - -		case DELIMIT: - +			errOut("Unexpected token in file root", t)  		}  		tmp = Node{Data: t} |