diff options
| author | Kyle Gunger <kgunger12@gmail.com> | 2022-04-09 05:55:03 -0400 | 
|---|---|---|
| committer | Kyle Gunger <kgunger12@gmail.com> | 2022-04-09 05:55:03 -0400 | 
| commit | 74aa33808dbe2630eb5fac427874428d55011267 (patch) | |
| tree | cc5912214deea1a0f6453c67c6bce6eb586d23ab | |
| parent | b76d0fe41b222acfa5348edecbe88277739cf3e9 (diff) | |
TINT v1 (PRE-ALPHA)
+ Added support for else/else if blocks
+ Fixed a bug with parsing string literals
+ Tested printing values to the cli
+ I think file writing/reading should work but it's a little hit or miss atm
| -rw-r--r-- | src/texec/eval.go | 99 | ||||
| -rw-r--r-- | src/texec/libtnsl.go | 35 | 
2 files changed, 95 insertions, 39 deletions
| diff --git a/src/texec/eval.go b/src/texec/eval.go index 4d06ee1..f88c5e2 100644 --- a/src/texec/eval.go +++ b/src/texec/eval.go @@ -363,7 +363,7 @@ func getStringLiteral(v tparse.Node) []interface{} {  	out := []interface{}{}  	for i := 0; i < len(dat); i++ { -		out = append(out, dat) +		out = append(out, dat[i])  	}  	return out @@ -601,12 +601,6 @@ func resolveArtifactCall(a TArtifact, params []TVariable) TVariable {  		} else {  			errOut("Need at least one arg to call tnsl.io func")  		} -	} else if tres == 1 { -		if len(params) > 1 { -			return tnslFileEval(params[0], params[1], a.Name) -		} else { -			errOut("Not enough args recieved to call tnsl.io.File method.") -		}  	}  	blk, pth := searchNode(a) @@ -625,6 +619,26 @@ func resolveArtifactCall(a TArtifact, params []TVariable) TVariable {  }  func resolveStructCall(a TArtifact, method string, params []TVariable) TVariable { +	if len(a.Path) > 0 && a.Path[0] == "tnsl" { +		a.Path = append(a.Path, a.Name) +		a.Name = method +		tres := tnslResolve(a) + +		if a.Name == "close" { +			params = append(params, null) +		} + +		if tres == 1 { +			if len(params) > 1 { +				return tnslFileEval(TVariable{tFile, *(params[0].Data.(*interface{}))}, params[1], a.Name) +			} else { +				errOut("Not enough args recieved to call tnsl.io.File method.") +			} +		} else { +			return null +		} +	} +  	blk, pth := searchNode(a)  	if blk == nil { @@ -702,7 +716,7 @@ func evalCIN(v tparse.Node, ctx *VarMap, wk *TVariable) *TVariable {  		pth := wk.Type.T  		if wk != nil && wk.Data != nil {  			args = append(args, *wk) -		}  +		}  		for i := 0; i < len(v.Sub[0].Sub); i++ {  			args = append(args, *evalValue(v.Sub[0].Sub[i], ctx)) @@ -909,17 +923,26 @@ func evalValue(v tparse.Node, ctx *VarMap) *TVariable {  				return &null  			}  			return &TVariable{ref.Type, *(ref.Data.(*interface{}))} -		case "!": -			a := convertVal(evalValue(v.Sub[0], ctx), tBool) -			return &TVariable{tBool, !(a.Data.(bool))} -		case "len": -			a := evalValue(v.Sub[0], ctx) -			return &TVariable{tInt, len(a.Data.([]interface{}))} -		case "~": -			a := evalValue(v.Sub[0], ctx) -			typ := a.Type -			typ.Pre = append([]string{"~"}, typ.Pre...) -			return &TVariable{typ, &(a.Data)} +		} + +		if len(v.Sub) == 1 { +			switch v.Data.Data { +			case "!": +				a := convertVal(evalValue(v.Sub[0], ctx), tBool) +				return &TVariable{tBool, !(a.Data.(bool))} +			case "len": +				a := evalValue(v.Sub[0], ctx) +				return &TVariable{tInt, len(a.Data.([]interface{}))} +			case "~": +				a := evalValue(v.Sub[0], ctx) +				typ := a.Type +				typ.Pre = append([]string{"~"}, typ.Pre...) +				return &TVariable{typ, &(a.Data)} +			case "-": +				a := convertVal(evalValue(v.Sub[0], ctx), tFloat) +				a.Data = -(a.Data.(float64)) +				return a +			}  		}  		// General case setup @@ -991,6 +1014,7 @@ func evalDef(v tparse.Node, ctx *VarMap) {  func evalCF(v tparse.Node, ctx *VarMap) (bool, TVariable, int) {  	loop := true +	ifout := true  	cond := tparse.Node{tparse.Token{tparse.LITERAL, "true", -1, -1}, []tparse.Node{}}  	var after *tparse.Node = nil @@ -999,7 +1023,7 @@ func evalCF(v tparse.Node, ctx *VarMap) (bool, TVariable, int) {  		for i := 0; i < len(v.Sub[0].Sub); i++ {  			switch v.Sub[0].Sub[i].Data.Data { -			case "if": +			case "if", "else":  				loop = false  			case "()":  				before = &(v.Sub[0].Sub[i]) @@ -1016,12 +1040,13 @@ func evalCF(v tparse.Node, ctx *VarMap) (bool, TVariable, int) {  				val := *evalValue(before.Sub[i].Sub[0], ctx)  				if i == len(before.Sub) - 1 && equateType(val.Type, tBool) {  					cond = before.Sub[i].Sub[0] +					ifout = val.Data.(bool)  				}  			}  		}  	} -	 -	for ; evalValue(cond, ctx).Data.(bool) ; { + +	for ; (!loop && ifout) || evalValue(cond, ctx).Data.(bool) ; {  		for i := 0; i < len(v.Sub); i++ {  			switch v.Sub[i].Data.Data {  			case "define": @@ -1039,6 +1064,16 @@ func evalCF(v tparse.Node, ctx *VarMap) (bool, TVariable, int) {  					goto CONCF  				} else if brk > 0 {  					return false, null, brk - 1 +				} else if equateType(val.Type, tIF) { +					if val.Data.(bool) == true { +						i++ + +						for ;i < len(v.Sub) && getNames(v.Sub[i])[0] == "else"; i++ {} +						 +						if i < len(v.Sub) { +							i-- +						} +					}  				}  			case "return":  				if len(v.Sub[i].Sub) > 0 { @@ -1089,6 +1124,10 @@ func evalCF(v tparse.Node, ctx *VarMap) (bool, TVariable, int) {  		}  	} +	if !loop { +		return false, TVariable{tIF, ifout}, 0 +	} +  	return false, null, 0  } @@ -1142,6 +1181,22 @@ func evalBlock(b tparse.Node, params []TVariable, method bool) TVariable {  			ret, val, _ := evalCF(b.Sub[i], &ctx)  			if ret {  				return *convertVal(&val, rty) +			} else if equateType(val.Type, tIF) { +				if val.Data.(bool) == true { +					i++ + +					for ;i < len(b.Sub) && b.Sub[i].Data.Data == "block"; { +						if getNames(b.Sub[i])[0] == "else" { +							i++ +						} else { +							break +						} +					} +					 +					if i < len(b.Sub) { +						i-- +					} +				}  			}  		case "return":  			return *convertVal(evalValue(b.Sub[i].Sub[0], &ctx), rty) diff --git a/src/texec/libtnsl.go b/src/texec/libtnsl.go index 6fe431b..0f02f32 100644 --- a/src/texec/libtnsl.go +++ b/src/texec/libtnsl.go @@ -56,6 +56,9 @@ var (  	// used only in module definintion  	tEnum = TType{Pre: []string{}, T: TArtifact{Path: []string{}, Name: "enum"}, Post: ""}  	tStruct = TType{Pre: []string{}, T: TArtifact{Path: []string{}, Name: "struct"}, Post: ""} + +	// Special types for if chain checking +	tIF = TType{Pre: []string{}, T: TArtifact{Path: []string{}, Name: "if"}, Post: ""}  )  // tells if the stub supports a function @@ -114,30 +117,28 @@ func tnslFileEval(file, in TVariable, function string) TVariable {  // Generic IO funcs  func tprint(in TVariable) { -	if equateType(in.Type, tString) { -		fmt.Print(in.Data.(string)) -	} else if equateType(in.Type, tCharp) { -		fmt.Print(in.Data.(rune)) -	} else { -		fmt.Print(in.Data) -	} +	fmt.Print(in.Data)  }  func tprintln(in TVariable) { -	if equateType(in.Type, tString) { -		fmt.Println(in.Data.(string)) -	} else if equateType(in.Type, tCharp) { -		fmt.Println(in.Data.(rune)) -	} else { -		fmt.Println(in.Data) +	fmt.Println(in.Data) +} + +func datToString(dat interface{}) string { +	out := []byte{} +	in := dat.([]interface{}) +	for i := 0; i < len(in); i++ { +		out = append(out, in[i].(byte))  	} + +	return string(out)  }  func topenWriteFile(in TVariable) TVariable { -	if equateType(in.Type, tString) { +	if !equateType(in.Type, tString) {  		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)) +	fd, err := os.Create(datToString(in.Data))  	if err != nil {  		panic(fmt.Sprintf("Failed to open file (for writing) %v as requested by the program. Aborting.\n%v", in.Data, err))  	} @@ -145,10 +146,10 @@ func topenWriteFile(in TVariable) TVariable {  }  func topenReadFile(in TVariable) TVariable { -	if equateType(in.Type, tString) { +	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)) +	fd, err := os.Open(datToString(in.Data))  	if err != nil {  		panic(fmt.Sprintf("Failed to open file (for reading) %v as requested by the program. Aborting.\n%v", in.Data, err))  	} |