diff options
| author | Kyle Gunger <kgunger12@gmail.com> | 2021-08-30 19:07:26 -0400 | 
|---|---|---|
| committer | Kyle Gunger <kgunger12@gmail.com> | 2021-08-30 19:07:26 -0400 | 
| commit | ea5ef2fe245c09b35c783977928d6e995110cfb4 (patch) | |
| tree | e25f71adb433bba34b10c3a013d8b10c24f159e3 /src | |
| parent | 628dd83397c47ff484f7c81b06dcd6d1e4af628b (diff) | |
Scrap old spec, add initial value parsing
Diffstat (limited to 'src')
| -rw-r--r-- | src/tparse/tree-preproc.go | 49 | ||||
| -rw-r--r-- | src/tparse/tree-value.go | 138 | ||||
| -rw-r--r-- | src/tparse/tree.go | 4 | ||||
| -rw-r--r-- | src/tparse/type.go | 5 | 
4 files changed, 179 insertions, 17 deletions
| 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, |