summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/texec/eval.go99
-rw-r--r--src/texec/libtnsl.go35
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))
}