diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/texec/eval.go | 234 | ||||
| -rw-r--r-- | src/texec/libtnsl.go | 29 | 
2 files changed, 166 insertions, 97 deletions
| diff --git a/src/texec/eval.go b/src/texec/eval.go index 29b49a0..f2b420f 100644 --- a/src/texec/eval.go +++ b/src/texec/eval.go @@ -369,6 +369,16 @@ func getIntLiteral(v tparse.Node) int {  	return int(i)  } +func getFloatLiteral(v tparse.Node) float64 { +	i, err := strconv.ParseFloat(v.Data.Data, 64) + +	if err != nil { +		errOut(fmt.Sprintf("Failed to parse float literal. %v", v.Data)) +	} + +	return float64(i) +} +  func getLiteralComposite(v tparse.Node) []interface{} {  	out := []interface{}{} @@ -379,8 +389,10 @@ func getLiteralComposite(v tparse.Node) []interface{} {  			out = append(out, getCharLiteral(v.Sub[i]))  		} else if v.Sub[i].Data.Data == "comp" {  			out = append(out, getLiteralComposite(v.Sub[i])) -		} else { +		} else if v.Sub[i].Data.Data[0] == '0' {  			out = append(out, getIntLiteral(v.Sub[i])) +		} else { +			out = append(out, getFloatLiteral(v.Sub[i]))  		}  	} @@ -392,15 +404,16 @@ func getBoolLiteral(v tparse.Node) bool {  }  func getLiteral(v tparse.Node, t TType) interface{} { - -	if equateType(t, tInt) { -		return getIntLiteral(v) +	if equateType(t, tFloat) { +		return getFloatLiteral(v)  	} else if equateType(t, tCharp) {  		return getCharLiteral(v)  	} else if equateType(t, tString) {  		return getStringLiteral(v)  	} else if equateType(t, tBool) { -		getBoolLiteral(v) +		return getBoolLiteral(v) +	} else if equateType(t, tInt) { +		return getIntLiteral(v)  	}  	return getLiteralComposite(v) @@ -415,20 +428,20 @@ func getLiteralType(v tparse.Node) TType {  		return tStruct  	} else if v.Data.Data == "true" || v.Data.Data == "false" {  		return tBool -	} else { +	} else if v.Data.Data[0] == '0' {  		return tInt +	} else { +		return tFloat  	} - -	return tNull  }  // Convert Value to Struct from Array (cvsa)  // USE ONLY IN THE CASE OF tStruct! -func cvsa(sct TType, dat []interface{}) VarMap { -	sv := searchDef(sct.T) +func cvsa(sct TArtifact, dat []interface{}) VarMap { +	sv := searchDef(sct)  	old_c := cart -	cart = sct.T +	cart = sct  	vars := sv.Data.([]TVariable)  	if len(vars) != len(dat) { @@ -440,9 +453,7 @@ func cvsa(sct TType, dat []interface{}) VarMap {  	for i:=0;i<len(vars);i++ {  		tmp := TVariable{vars[i].Type, nil}  		if isStruct(vars[i].Type, 0) { -			tmp.Data = cvsa(vars[i].Type, dat[i].([]interface{})) -		} else if isArray(vars[i].Type, 0) { -			tmp.Data = cata(vars[i].Type, 1, dat[i].([]interface{})) +			tmp.Data = cvsa(vars[i].Type.T, dat[i].([]interface{}))  		} else {  			tmp.Data = dat[i]  		} @@ -454,75 +465,99 @@ func cvsa(sct TType, dat []interface{}) VarMap {  	return out  } -// Copy Array To Array (cata) -// USE ONLY IN CASE OF tStruct! -func cata(str TType, skp int, dat []interface{}) interface{} { -	if isArray(str, skp) { -		out := []interface{}{} -		for i := 0; i < len(dat); i++ { -			out = append(out, cata(str, skp + 1, dat[i].([]interface{}))) -		} -		return out -	} else if isStruct(str, skp) { -		out := []VarMap{} -		for i := 0; i < len(dat); i++ { -			out = append(out, cvsa(str, dat[i].([]interface{}))) +// Copy aray to aray (cata) +func cata(st TArtifact, dat []interface{}) []interface{} { +	out := []interface{}{} + +	for i := 0; i < len(dat); i++ { +		switch v := dat[i].(type) { +		case []interface{}: +			out = append(out, cata(st, dat)) +		case VarMap: +			out = append(out, csts(st, v)) +		default: +			out = append(out, v)  		} -		return out  	} -	if equateTypePSO(str, tInt, skp) { -		out := []int{} -		for i := 0; i < len(dat); i++ { -			out = append(out, dat[i].(int)) -		} -		return out -	} else if equateTypePSO(str, tByte, skp) || equateTypePSO(str, tCharp, skp) { -		out := []byte{} -		for i := 0; i < len(dat); i++ { -			out = append(out, dat[i].(byte)) -		} -		return out -	} else if equateTypePSO(str, tFloat, skp) { -		out := []float64{} -		for i := 0; i < len(dat); i++ { -			out = append(out, dat[i].(float64)) +	return out +} + +// Copy struct to struct +// Makes a deep copy of a struct. +func csts(st TArtifact, dat VarMap) VarMap { +	sv := searchDef(st) +	 +	old_c := cart +	cart = st +	 +	vars := sv.Data.([]TVariable) + +	out := make(VarMap) + +	for i := 0; i < len(vars); i++ { +		var dts interface{} = nil + +		switch v := dat[vars[i].Data.(string)].Data.(type) { +		case []interface{}: +			dts = cata(vars[i].Type.T, v) +		case VarMap: +			dts = csts(vars[i].Type.T, v) +		default: +			dts = v  		} -		return out +		 +		out[vars[i].Data.(string)] = &TVariable{vars[i].Type, dts}  	} -	errOut("Unknown cata error.") -	return nil +	cart = old_c + +	return out  } -func convertValPS(from, to TType, sk int, dat interface{}) interface{} { -	if equateTypePSO(from, tStruct, sk) { +func convertValPS(to TType, sk int, dat interface{}) interface{} { +	var numcv float64 +	switch v := dat.( type ) { +	case []interface{}:  		if isStruct(to, sk) { -			return cvsa(to, dat.([]interface{})) +			return cvsa(to.T, v)  		} else if isArray(to, sk) { -			return cata(to, sk + 1, dat.([]interface{})) -		} -	} else if isArray(from, sk) { -		if isArray(to, sk) { -			out := []interface{}{} -			for i := 0; i < len(dat.([]interface{}));i++ { -				out = append(out, convertValPS(from, to, sk + 1, dat.([]interface{})[i])) -			} -		} -	} else if equateTypePSO(from, tInt, sk) { -		if equateTypePSO(to, tInt, sk) { -			return dat.(int) -		} else if equateTypePSO(to, tCharp, sk) { -			return dat.(byte) +			return cata(to.T, v)  		} +	case VarMap: +		return csts(to.T, v) +	case int: +		numcv = float64(v) +		goto NCV +	case byte: +		numcv = float64(v) +		goto NCV +	case float64: +		numcv = v +		goto NCV +		 +	} + +	errOut(fmt.Sprintf("Unable to convert between two types.\nTO: %v\nSK: %d\nDT: %v", to, sk, dat)) +	return nil + +	NCV: +	if equateTypePSO(to, tInt, sk) { +		return int(numcv) +	} else if equateTypePSO(to, tFloat, sk) { +		return float64(numcv) +	} else if equateTypePSO(to, tByte, sk) { +		return byte(numcv) +	} else if equateTypePSO(to, tBool, sk) { +		return numcv == 0  	} -	errOut(fmt.Sprintf("Unable to convert between two types.\nFR: %v\nTO: %v\nSK: %d\nDT: %v", from, to, sk, dat)) +	errOut(fmt.Sprintf("Unable to convert between two types.\nTO: %v\nSK: %d\nDT: %v", to, sk, dat))  	return nil  }  func convertVal(dat TVariable, to TType) interface{} { -	return convertValPS(dat.Type, to, 0, dat.Data) +	return convertValPS(to, 0, dat.Data)  }  //##################### @@ -549,15 +584,15 @@ func resolveArtifactCall(a TArtifact, params []TVariable) TVariable {  }  func resolveArtifact(a TArtifact, ctx *VarMap) *TVariable { -	if len(a.Path) == 0 { -		val, prs := (*ctx)[a.Name] -		if !prs { +	val, prs := (*ctx)[a.Name] +	if !prs || len(a.Path) != 0 { +		// Try searching the modules for it +		val = searchDef(a) +		if val == nil {  			errOutCTX(fmt.Sprintf("Could not resolve %s in the current context.", a.Name), ctx)  		} -		return val  	} - -	return nil +	return val  }  //################# @@ -671,12 +706,7 @@ func evalValue(v tparse.Node, ctx *VarMap) *TVariable {  			}  		} -		out, prs := (*ctx)[v.Data.Data] -		if prs { -			return out -		} -		 -		errOutCTX(fmt.Sprintf("Unable to find variable %s when parsing value.", v.Data.Data), ctx) +		return resolveArtifact(TArtifact{[]string{}, v.Data.Data}, ctx)  	case tparse.AUGMENT:  		// Special case for = @@ -738,14 +768,18 @@ func evalValue(v tparse.Node, ctx *VarMap) *TVariable {  	return &null  } -// Generate a value for a definition -func evalDefVal(v tparse.Node, ctx *VarMap) { - -} -  // Eval a definition  func evalDef(v tparse.Node, ctx *VarMap) { - +	t := getType(v.Sub[0]) +	 +	for i := 0; i < len(v.Sub[1].Sub); i++ { +		if v.Sub[1].Sub[i].Data.Data == "=" { +			(*ctx)[v.Sub[1].Sub[i].Sub[0].Data.Data] = &TVariable{t, convertVal(*evalValue(v.Sub[1].Sub[i].Sub[1], ctx), t)} +		} else { +			(*ctx)[v.Sub[1].Sub[i].Data.Data] = &TVariable{t, nil} +		} +		 +	}  }  // Eval a control flow @@ -754,22 +788,46 @@ func evalCF(v tparse.Node, ctx *VarMap) (bool, TVariable) {  	return false, null  } +func evalParams(pd tparse.Node, params *[]TVariable, ctx *VarMap) { + +} +  func evalBlock(b tparse.Node, params []TVariable) TVariable {  	ctx := make(VarMap) +	var rty TType = tNull + +	if b.Sub[0].Data.Data == "bdef" { +		for i := 0; i < len(b.Sub[0].Sub); i++ { +			if b.Sub[0].Sub[i].Data.Data == "[]" { +				rty = getType(b.Sub[0].Sub[i].Sub[0]) +			} else if b.Sub[0].Sub[i].Data.Data == "()" { +				evalParams(b.Sub[0].Sub[i], ¶ms, &ctx) +			} +		} +	} +  	for i := 0; i < len(b.Sub); i++ {  		switch b.Sub[i].Data.Data {  		case "define":  			evalDef(b.Sub[i], &ctx)  		case "value": -			evalValue(b.Sub[i], &ctx) +			fmt.Println("--- Eval Value ---") +			fmt.Println(b.Sub[i].Sub[0]) +			fmt.Println(*evalValue(b.Sub[i].Sub[0], &ctx)) +			fmt.Println("--- End Value ---")  		case "block": -			ret, val := evalCF(b.Sub[i], &ctx) +			ret, val := evalCF(b.Sub[i].Sub[0], &ctx)  			if ret { -				return val +				return TVariable{rty, convertVal(val, rty)}  			}  		case "return": -			return *evalValue(b.Sub[i].Sub[0], &ctx) +			fmt.Println("--- Block return ---") +			fmt.Println(b.Sub[i].Sub[0].Sub[0]) +			ret := *evalValue(b.Sub[i].Sub[0].Sub[0], &ctx) +			fmt.Println(ret) +			fmt.Println("--- Return end ---") +			return TVariable{rty, convertVal(ret, rty)}  		}  	} diff --git a/src/texec/libtnsl.go b/src/texec/libtnsl.go index cd2077a..6c34473 100644 --- a/src/texec/libtnsl.go +++ b/src/texec/libtnsl.go @@ -26,7 +26,7 @@ import (  	Parts included:  		- io.print  		- io.println -		- io.open_file +		- io.openFile  		- io.File API for file objects  	Types included: @@ -63,8 +63,7 @@ func tnslResolve(callPath TArtifact) int {  	l := len(callPath.Path)  	if l < 2 || l > 3 || callPath.Path[0] != "tnsl" || callPath.Path[1] != "io" {  		return -1 -	} -	if l > 2 && callPath.Path[2] != "File" { +	} else if l > 2 && callPath.Path[2] != "File" {  		return -1  	} @@ -73,7 +72,7 @@ func tnslResolve(callPath TArtifact) int {  			return 1;  		}  	} else { -		if callPath.Name == "print" || callPath.Name == "println" || callPath.Name == "open_file" { +		if callPath.Name == "print" || callPath.Name == "println" || callPath.Name == "readFile" || callPath.Name == "writeFile" {  			return 0;  		}  	} @@ -91,8 +90,10 @@ func tnslEval(in TVariable, function string) TVariable {  		tprint(in)  	case "println":  		tprintln(in) -	case "open_file": -		return topen_file(in) +	case "readFile": +		return topenReadFile(in) +	case "writeFile": +		return topenWriteFile(in)  	}  	return TVariable{tNull, nil}  } @@ -132,17 +133,27 @@ func tprintln(in TVariable) {  	}  } -func topen_file(in TVariable) TVariable { +func topenWriteFile(in TVariable) TVariable {  	if equateType(in.Type, tString) { -		panic("Tried to open a file, but did not use a string type for the file name.") +		panic("Tried to open a file (for writing), but did not use a string type for the file name.")  	}  	fd, err := os.Create(in.Data.(string))  	if err != nil { -		panic(fmt.Sprintf("Failed to open file %v as requested by the program. Aborting.\n%v", in.Data, err)) +		panic(fmt.Sprintf("Failed to open file (for writing) %v as requested by the program. Aborting.\n%v", in.Data, err))  	}  	return  TVariable{tFile, fd}  } +func topenReadFile(in TVariable) TVariable { +	if equateType(in.Type, tString) { +		panic("Tried to open a file (for reading), but did not use a string type for the file name.") +	} +	fd, err := os.Open(in.Data.(string)) +	if err != nil { +		panic(fmt.Sprintf("Failed to open file (for reading) %v as requested by the program. Aborting.\n%v", in.Data, err)) +	} +	return  TVariable{tFile, fd} +}  // File API |