summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyle Gunger <kgunger12@gmail.com>2022-04-07 00:47:20 -0400
committerKyle Gunger <kgunger12@gmail.com>2022-04-07 00:47:20 -0400
commitda6f4e15ad2fa3edd59108913065c883aee897ed (patch)
tree4f37118329733febbfb19e3d6528d44331312429
parent9d2b6e985b008492fc99a79f1f674cc2ea83be2f (diff)
[EXEC] A few updates
+ Value conversion + Value deep copy + The most basic program (returning 0) works + Opening a file to read is now differnet from opening a file to write
-rw-r--r--src/texec/eval.go236
-rw-r--r--src/texec/libtnsl.go29
2 files changed, 167 insertions, 98 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.\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
+
+ 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.\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], &params, &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