diff options
| author | Kyle Gunger <kgunger12@gmail.com> | 2022-03-16 22:00:39 -0400 | 
|---|---|---|
| committer | Kyle Gunger <kgunger12@gmail.com> | 2022-03-16 22:00:39 -0400 | 
| commit | 8e3f15e37f9fec06acc6a309be77098c6614e9d3 (patch) | |
| tree | 6f6fda411927e866ef0fdef16fec17b07faa3779 /src/texec | |
| parent | d581c7503f20a8b560a98e521daec632c763c56c (diff) | |
[EXEC] Refactor value eval
Diffstat (limited to 'src/texec')
| -rw-r--r-- | src/texec/eval.go | 112 | 
1 files changed, 59 insertions, 53 deletions
| diff --git a/src/texec/eval.go b/src/texec/eval.go index 3eca821..74042a0 100644 --- a/src/texec/eval.go +++ b/src/texec/eval.go @@ -333,6 +333,10 @@ func getType(t tparse.Node) TType {  	return out  } +func stripType(t TType, s int) TType { +	return TType{t.Pre[s:], t.T, t.Post} +} +  // Value generation  func getStringLiteral(v tparse.Node) []byte { @@ -420,8 +424,8 @@ func getLiteralType(v tparse.Node) TType {  // Convert Value to Struct from Array (cvsa)  // USE ONLY IN THE CASE OF tStruct! -func cvsa(str TType, skip int, dat []interface{}) VarMap { -	sv := searchDef(str) +func cvsa(sct TType, dat []interface{}) VarMap { +	sv := searchDef(sct.T)  	vars := sv.Data.([]TVariable)  	if len(vars) != len(cmp) { @@ -473,8 +477,8 @@ func convertValPS(from, to TType, sk int, dat interface{}) interface{} {  	return nil  } -func convertVal(from, to TType, dat interface{}) interface{} { -	return convertValPS(from, to, 0, dat) +func convertVal(dat TVariable, to TType) interface{} { +	return convertValPS(dat.Type, to, 0, dat.Data)  }  //##################### @@ -574,72 +578,74 @@ func evalDotChain(v tparse.Node, ctx *VarMap, wk *TVariable) *TVariable {  	return &null  } -func evalSet(v tparse.Node, ctx *VarMap, val TVariable) { +// Parse a value node +func evalValue(v tparse.Node, ctx *VarMap) *TVariable { +	switch v.Data.Type { +	case tparse.LITERAL: +		t := getLiteralType(v) +		return &TVariable{t, getLiteral(v, t)} +	case tparse.DEFWORD: -} +	case tparse.AUGMENT: +		// Special case for = +		if v.Data.Data == "=" { +			sv := evalValue(v.Sub[0], ctx) +			rv := evalValue(v.Sub[1], ctx) +			(*sv).Data = convertVal(*rv, *sv.Type) +			return rval -// Parse a value node -func evalValue(v tparse.Node, ctx *VarMap) TVariable { -	if v.Data.Type == tparse.LITERAL { -		if v.Data.Data[0] == '"' { -			return TVariable{tString, getStringLiteral(v)} -		} else if v.Data.Data[0] == '\'' { -			return TVariable{tCharp, getCharLiteral(v)} -		} else if v.Data.Data == "comp" { -			return TVariable{tStruct, getLiteralComposite(v)} -		} else { -			return TVariable{tInt, getIntLiteral(v)} +		} else if v.Data.Data == "." { +			return evalDotChain(v, ctx, &null) + +		} else if v.Data.Data == "!" { + +			a := evalValue(v.Sub[0], ctx) +			return TVariable{tBool, !(a.Data.(bool))}  		} -	} else if v.Data.Type == tparse.DEFWORD { -	} else if v.Data.Type == tparse.AUGMENT { +		// General case setup +		 +		a, b := evalValue(v.Sub[0]), evalBlock(v.Sub[1]) +		var out TVariable +		out.Type = tInt + +		// General math and bool cases  		switch v.Data.Data { -		case "=": -			rval := evalValue(v.Sub[1], ctx) -			evalSet(v.Sub[0], ctx, rval) -			return rval  		case "+": -			a := evalValue(v.Sub[0], ctx) -			b := evalValue(v.Sub[1], ctx) -			return TVariable{tInt, a.Data.(int) + b.Data.(int)} +			out.Data = a.Data.(int) + b.Data.(int)  		case "-": -			a := evalValue(v.Sub[0], ctx) -			b := evalValue(v.Sub[1], ctx) -			return TVariable{tInt, a.Data.(int) - b.Data.(int)} +			out.Data = a.Data.(int) - b.Data.(int)  		case "*": -			a := evalValue(v.Sub[0], ctx) -			b := evalValue(v.Sub[1], ctx) -			return TVariable{tInt, a.Data.(int) * b.Data.(int)} +			out.Data = a.Data.(int) * b.Data.(int)  		case "/": -			a := evalValue(v.Sub[0], ctx) -			b := evalValue(v.Sub[1], ctx) -			return TVariable{tInt, a.Data.(int) / b.Data.(int)} +			out.Data = a.Data.(int) / b.Data.(int)  		case "%": -			a := evalValue(v.Sub[0], ctx) -			b := evalValue(v.Sub[1], ctx) -			return TVariable{tInt, a.Data.(int) % b.Data.(int)} +			out.Data = a.Data.(int) % b.Data.(int)  		case "&&": -			a := evalValue(v.Sub[0], ctx) -			b := evalValue(v.Sub[1], ctx) -			return TVariable{tBool, a.Data.(bool) && b.Data.(bool)} +			out.Type = tBool +			out.Data = a.Data.(bool) && b.Data.(bool)  		case "||": -			a := evalValue(v.Sub[0], ctx) -			b := evalValue(v.Sub[1], ctx) -			return TVariable{tInt, a.Data.(bool) || b.Data.(bool)} +			out.Type = tBool +			out.Data = a.Data.(bool) || b.Data.(bool)  		case "==": -			a := evalValue(v.Sub[0], ctx) -			b := evalValue(v.Sub[1], ctx) +			out.Type = tBool +			if equateType(a.Type, b.Type) { +				out.Data = a.Data == b.Data +			} else { +				out.Data = a.Data.(int) == b.Data.(int) +			} +		case "!=": +			out.Type = tBool  			if equateType(a.Type, b.Type) { -				return TVariable{tBool, a.Data == b.Data} +				out.Data = a.Data != b.Data +			} else { +				out.Data = a.Data.(int) != b.Data.(int)  			} -			return TVariable{tBool, a.Data.(int) == b.Data.(int)} -		case "!": -			a := evalValue(v.Sub[0], ctx) -			return TVariable{tBool, !(a.Data.(bool))} -		case ".": -			return *evalDotChain(v, ctx, &null)  		} + +		return &out  	} +  	return null  } |