diff options
| author | Kyle Gunger <kgunger12@gmail.com> | 2021-10-29 20:06:51 -0400 | 
|---|---|---|
| committer | Kyle Gunger <kgunger12@gmail.com> | 2021-10-29 20:06:51 -0400 | 
| commit | 3395cd7dc356b61fe48ee9d755eef8a7b19ee9f1 (patch) | |
| tree | 7ff4dcc5fc9e24021fd5d754a8a8ecd2df3a6df4 | |
| parent | 8502bdd410c5a685a66a218fa97ddd2e7d207d30 (diff) | |
[AST] Statement parsing (incomplete)
Still need to figure out a check for a type followed by a value
| -rw-r--r-- | qualifiers.txt | 2 | ||||
| -rw-r--r-- | small-tests/base.tnsl | 3 | ||||
| -rw-r--r-- | small-tests/examp.tnsl | 4 | ||||
| -rw-r--r-- | src/tparse/tree-statement.go | 146 | ||||
| -rw-r--r-- | src/tparse/tree-value.go | 13 | ||||
| -rw-r--r-- | tests/block-test.tnsl | 74 | ||||
| -rw-r--r-- | tests/literal-test.tnsl | 7 | ||||
| -rw-r--r-- | tests/parameter-test.tnsl | 2 | 
8 files changed, 165 insertions, 86 deletions
| diff --git a/qualifiers.txt b/qualifiers.txt index 835a5f5..18c447f 100644 --- a/qualifiers.txt +++ b/qualifiers.txt @@ -22,7 +22,6 @@ structure of blocks:  (block start)      interface (defword) -    enum (defword) (return type list)      loop (bool params) (loop rets)      if (bool params) @@ -60,6 +59,7 @@ keyword statements:  delete (list of defwords)*  struct (defword) (struct params)* +enum (defword) (return type list) (enum values)  continue  break  label (defword) diff --git a/small-tests/base.tnsl b/small-tests/base.tnsl index f291cf3..157b65b 100644 --- a/small-tests/base.tnsl +++ b/small-tests/base.tnsl @@ -2,4 +2,5 @@  ;a.pl()  # Same -; a . pl ()
\ No newline at end of file +; a . pl () + diff --git a/small-tests/examp.tnsl b/small-tests/examp.tnsl index 196db40..f8579a0 100644 --- a/small-tests/examp.tnsl +++ b/small-tests/examp.tnsl @@ -19,7 +19,7 @@  # pass a variable  ;int s = 3 -;byte bitbyte = .2 +;int8 bitbyte = .2  # generic scope block @@ -120,7 +120,7 @@  ;/ -/; switch (i) +/; match (i)    # You can do stuff here as well    ;int t = 0 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  } diff --git a/tests/block-test.tnsl b/tests/block-test.tnsl index 6dde05f..c48d7de 100644 --- a/tests/block-test.tnsl +++ b/tests/block-test.tnsl @@ -1,47 +1,49 @@  /# -   Copyright 2020 Kyle Gunger +	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 +	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 +		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. +	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.  #/ -/;if (i==0) -    ;i = 2 -;/ -/:  include -    "this" -    "that" -:/ +/; main +	;int i = 0 -# ;; can be used as a quick block re-definition +	/;if (i==0) +		;i = 2 +	;/ -/;if (i==0) -    ;i = 2 -;;else -    ;i = 0 -;/ +	/:  include +		"this" +		"that" +	:/ -# Comment block switching +	# ;; can be used as a quick block re-definition -/; if (i == 2) -    ;i = 4 -;# -    Comment -#; else -    ;i = 6 -;/ +	/;if (i==0) +		;i = 2 +	;;else +		;i = 0 +	;/ -/; main +	# Comment block switching + +	/; if (i == 2) +		;i = 4 +	;# +		Comment +	#; else +		;i = 6 +	;/  ;/  /; module vec @@ -51,17 +53,17 @@  	/;method Vector2  		/; operator + (~Vector2 v) -			;self.x += `v.x -			;self.y += `v.y +			;self.x += v`.x +			;self.y += v`.y  		;/ -        /; operator + (int32 a) +		/; operator + (int32 a)  			;self.x += a  			;self.y += a  		;/  	;/ -    ;struct FVector2 () {} +	;struct FVector2 () {}  ;/
\ No newline at end of file diff --git a/tests/literal-test.tnsl b/tests/literal-test.tnsl index 1841159..73f5f77 100644 --- a/tests/literal-test.tnsl +++ b/tests/literal-test.tnsl @@ -15,8 +15,8 @@  #/  # These should all work -;[]char s = "\"" -;[]char st="\\" +;{}char s = "\"" +;{}char st="\\"  ;int i = 0  ;int j=1 @@ -40,4 +40,5 @@  ;int k = .1 -;int l = 0x01
\ No newline at end of file +;int l = 0x01 + diff --git a/tests/parameter-test.tnsl b/tests/parameter-test.tnsl index 254db75..96f6d41 100644 --- a/tests/parameter-test.tnsl +++ b/tests/parameter-test.tnsl @@ -13,6 +13,6 @@     See the License for the specific language governing permissions and     limitations under the License.  #/ - +;int another = 0  /; loop (int initial = 0, complex = 2) [initial < max || complex < 40, initial++, complex += 7, another += 2]  ;/ |