diff options
Diffstat (limited to 'src/texec')
| -rw-r--r-- | src/texec/eval.go | 161 | ||||
| -rw-r--r-- | src/texec/libtnsl.go | 1 | 
2 files changed, 124 insertions, 38 deletions
| diff --git a/src/texec/eval.go b/src/texec/eval.go index 880e7b6..ac183c0 100644 --- a/src/texec/eval.go +++ b/src/texec/eval.go @@ -397,7 +397,7 @@ func getLiteralComposite(v tparse.Node) []interface{} {  		if v.Sub[i].Data.Data[0] == '"' {  			out = append(out, getStringLiteral(v.Sub[i]))  		} else if v.Sub[i].Data.Data[0] == '\'' { -			out = append(out, getStringLiteral(v.Sub[i])) +			out = append(out, getCharLiteral(v.Sub[i]))  		} else if v.Sub[i].Data.Data == "comp" {  			out = append(out, getLiteralComposite(v.Sub[i]))  		} else { @@ -484,52 +484,137 @@ func resolveArtifact(a TArtifact, ctx *VarMap) *TVariable {  // Value statement parsing -func evalDotChain(v tparse.Node, ctx *VarMap) TVariable { +func isStruct(t TType, skp int) bool { +	ch := false + +	ch = ch || isPointer(t, skp) +	ch = ch || isArray(t, skp) +	ch = ch || equateTypePS(t, tFile, skp) +	ch = ch || equateTypePS(t, tInt, skp) +	ch = ch || equateTypePS(t, tByte, skp) +	ch = ch || equateTypePS(t, tFloat, skp) +	ch = ch || equateTypePS(t, tCharp, skp) +	ch = ch || equateTypePS(t, tBool, skp) +	ch = ch || equateTypePS(t, tNull, skp) + +	return !ch +} + +func isPointer(t TType, skp int) bool { +	for ;skp < len(t.Pre) && t.Pre[skp] == "const"; skp++ {} + +	if len(t.Pre) >= skp { +		return false +	} + +	return t.Pre[skp] == "~" +} + +func isArray(t TType, skp int) bool { +	for ;skp < len(t.Pre) && t.Pre[skp] == "const"; skp++ {} + +	if len(t.Pre) >= skp { +		return false +	} + +	return t.Pre[skp] == "{}" +} + +func evalDotChain(v tparse.Node, ctx *VarMap, wk *TVariable) TVariable { +	var wrvm *VarMap +	wrvm = ctx + +	if isStruct((*wk).Type, 0) { +		wrvm = (*wk).Data.(*VarMap) +	} + +	// Check if current name relates to a variable in context or working var +	dat, prs := (*wrvm)[v.Sub[0].Data.Data] +	if prs { +		return evalDotChain(v.Sub[1], ctx, dat) +	} + +	// + +  	return null  }  // Try to convert a value into a specific type -func convValue(val TVariable, t TType) TVariable { +func convValue(val *TVariable, t TType) TVariable { +	if equateType(val.Type, t) { +		return *val +	} + +	errOut(fmt.Sprintf("Failed to convert value %v to type %v.", val, t))  	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.Data { -	case "=": -		dtyp := (*(*ctx)[v.Sub[0].Data.Data]).Type -		dval := evalValue(v.Sub[1], ctx) -		(*ctx)[v.Sub[0].Data.Data].Data = (convValue(dval, dtyp)).Data -	case "+": -		a := evalValue(v.Sub[0], ctx) -		b := evalValue(v.Sub[1], ctx) -		return TVariable{tInt, 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)} -	case "*": -		a := evalValue(v.Sub[0], ctx) -		b := evalValue(v.Sub[1], ctx) -		return TVariable{tInt, 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)} -	case "&&": -		a := evalValue(v.Sub[0], ctx) -		b := evalValue(v.Sub[1], ctx) -		return TVariable{tBool, 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)} -	case "==": -		a := evalValue(v.Sub[0], ctx) -		b := evalValue(v.Sub[1], ctx) -		return TVariable{tBool, a.Data.(int) == b.Data.(int)} -	case ".": -		return evalDotChain(v, ctx) +	if v.Data.Type == tparse.AUGMENT { +		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)} +		case "-": +			a := evalValue(v.Sub[0], ctx) +			b := evalValue(v.Sub[1], ctx) +			return TVariable{tInt, 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)} +		case "/": +			a := evalValue(v.Sub[0], ctx) +			b := evalValue(v.Sub[1], ctx) +			return TVariable{tInt, 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)} +		case "&&": +			a := evalValue(v.Sub[0], ctx) +			b := evalValue(v.Sub[1], ctx) +			return TVariable{tBool, 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)} +		case "==": +			a := evalValue(v.Sub[0], ctx) +			b := evalValue(v.Sub[1], ctx) +			if equateType(a.Type, b.Type) { +				return TVariable{tBool, a.Data == b.Data} +			} +			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) +		} +	} else 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.Type == tparse.DEFWORD { +  	}  	return null  } diff --git a/src/texec/libtnsl.go b/src/texec/libtnsl.go index 2a2a9d5..cd2077a 100644 --- a/src/texec/libtnsl.go +++ b/src/texec/libtnsl.go @@ -51,6 +51,7 @@ var (  	tFloat = TType{Pre: []string{}, T: TArtifact{Path: []string{}, Name:"float"}, Post: ""}  	tCharp = TType{Pre: []string{}, T: TArtifact{Path: []string{}, Name:"charp"}, Post: ""}  	tNull = TType{Pre: []string{}, T: TArtifact{Path: []string{}, Name: "null"}, Post: ""} +	tBool = TType{Pre: []string{}, T: TArtifact{Path: []string{}, Name: "bool"}, Post: ""}  	// used only in module definintion  	tEnum = TType{Pre: []string{}, T: TArtifact{Path: []string{}, Name: "enum"}, Post: ""} |