From dc8f1a06f086bda90e90a5386d4619d54efb1d0d Mon Sep 17 00:00:00 2001 From: Kyle Gunger Date: Sat, 11 Dec 2021 23:32:16 -0500 Subject: [EVAL] Still needs some work + modules now define variables properly + fixed some bugs in eval.tnsl with type checking ~ Needs to support arrays and composites, but doesn't yet. --- src/texec/eval.go | 89 +++++++++++++++++++++++++++++------------------ src/texec/libtnsl.go | 3 ++ src/texec/worldbuilder.go | 45 ++++++++++++++++++++++-- src/tparse/tree-value.go | 6 ++-- 4 files changed, 105 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/texec/eval.go b/src/texec/eval.go index d1bf366..a360157 100644 --- a/src/texec/eval.go +++ b/src/texec/eval.go @@ -16,10 +16,11 @@ package texec -import "tparse" -import "fmt" - -import "strconv" +import ( + "tparse" + "fmt" + "strconv" +) /* So here's what I care to support at present: @@ -47,6 +48,14 @@ func errOut(msg string, place tparse.Token) { panic("EVAL ERROR") } +func errOutCTX(msg string, place tparse.Token, ctx TContext) { + fmt.Println("Error in eval:") + fmt.Println(msg) + fmt.Println(place) + fmt.Println(ctx) + panic("EVAL ERROR") +} + // Names of artifacts, finding artifacts func getDefNames(def tparse.Node) []string { @@ -127,33 +136,38 @@ func getArtifact(a TArtifact, root *TModule) *tparse.Node { // Type related stuff // Checking type equality +// Assumes a is an unknown type and b is a known good type. func equateTypePS(a, b TType, preskip int) bool { - if len(a.Pre) != len(b.Pre) || len(a.Post) != len(b.Post) { - return false - } else if len(a.T.Path) != len(b.T.Path) { + if len(a.T.Path) != len(b.T.Path) { + fmt.Println("thing 1") return false } for i := preskip; i < len(a.Pre); i++ { - if a.Pre[i] != b.Pre[i - preskip] { + if a.Pre[i] == "const" { + preskip++ + continue + } else if a.Pre[i] != b.Pre[i - preskip] { + fmt.Println("thing 3") return false } } for i := 0; i < len(a.T.Path); i++ { if a.T.Path[i] != b.T.Path[i] { + fmt.Println("thing 4") return false } } if a.T.Name != b.T.Name { + fmt.Println("thing 5") return false } - for i := 0; i < len(a.Post); i++ { - if a.Post[i] != b.Post[i] { - return false - } + if (a.Post == "`" && b.Post != "`") || (b.Post == "`" && a.Post != "`") { + fmt.Println("thing 6") + return false } return true; @@ -229,45 +243,50 @@ func getCharLiteral(v tparse.Node) byte { return byte(val) } -func getIntLiteral(v tparse.Node) int64 { +func getIntLiteral(v tparse.Node) int { i, err := strconv.ParseInt(v.Data.Data, 0, 64) if err != nil { errOut("Failed to parse integer literal.", v.Data) } - return i + return int(i) } -func getLiteral(v tparse.Node) (interface{}, TType) { - str, err := strconv.Unquote(v.Data.Data) +func getLiteralComposite(v tparse.Node) VarMap { + return VarMap{} +} - if err == nil { - return []byte(str), tString - } else { - val, mb, _, err := strconv.UnquoteChar(v.Data.Data, byte('\'')) - - if err == nil { - return byte(val), tCharp - } else { - i, err := strconv.ParseInt(v.Data.Data, 0, 64) +func getLiteral(v tparse.Node, t TType) interface{} { - if err == nil { - return i, tInt - } else { - errOut("Failed to parse literal in any way.", v.Data) - } - } + if equateType(t, tInt) { + return getIntLiteral(v) + } else if equateType(t, tCharp) { + return getCharLiteral(v) + } else if equateType(t, tString) { + return getStringLiteral(v) } - return nil, tNull + return getLiteralComposite(v) } + + //##################### //# Finding Artifacts # //##################### +func resolveModArtifact() *TVariable { + return nil +} + +func resolveArtifactCall() TVariable { + return TVariable{} +} +func resolveArtifact(a TArtifact, ctx *TContext, root *TModule) *TVariable { + return nil +} //################# //# Runtime funcs # @@ -278,4 +297,8 @@ func getLiteral(v tparse.Node) (interface{}, TType) { // Get a value from nodes. Must specify type of value to generate. func evalValue(v tparse.Node, t TType) TVariable { return TVariable{} -} \ No newline at end of file +} + +func evalBlock(b tparse.Node, m TArtifact) TVariable { + return TVariable{tNull, nil} +} diff --git a/src/texec/libtnsl.go b/src/texec/libtnsl.go index b1c1907..a5d4589 100644 --- a/src/texec/libtnsl.go +++ b/src/texec/libtnsl.go @@ -51,6 +51,9 @@ 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: ""} + + // used only in module definintion + tEnum = TType{Pre: []string{}, T: TArtifact{Path: []string{}, Name: "enum"}, Post: ""} ) // tells if the stub supports a function diff --git a/src/texec/worldbuilder.go b/src/texec/worldbuilder.go index 9fd29b7..5fc5683 100644 --- a/src/texec/worldbuilder.go +++ b/src/texec/worldbuilder.go @@ -45,10 +45,44 @@ func evalPreLiteral(n tparse.Node) string { return "" } -//Generate a variable for a module + +func modDef(n tparse.Node, m *TModule) { + t := getType(n.Sub[0]) + s, vs := modDefVars(n.Sub[1], t) + for i := 0; i < len(s); i++ { + m.Defs[s[i]] = vs[i] + } +} + +// Generate a variable list for a module // For sub = 0, give the vlist -func modDef(n tparse.Node, t TType, sub int) ([]string, []TVariable) { +// May be horribly broken. Definitely doesn't support composite types. +func modDefVars(n tparse.Node, t TType) ([]string, []TVariable) { + s := []string{} + v := []TVariable{} + for i := 0; i < len(n.Sub); i++ { + if n.Sub[i].Data.Type == tparse.DEFWORD { + s = append(s, n.Sub[i].Data.Data) + v = append(v, TVariable{t, nil}) + } else if n.Sub[i].Data.Data == "=" && n.Sub[i].Sub[0].Data.Type == tparse.DEFWORD { + s = append(s, n.Sub[i].Sub[0].Data.Data) + v = append(v, TVariable{t, getLiteral(n.Sub[i].Sub[1], t)}) + } else { + errOut("Unexpected thing in definition. Expected '=' or DEFWORD.", n.Sub[i].Data) + } + } + return s, v +} +func modDefEnum(n tparse.Node, m *TModule) { + name := n.Sub[0].Data.Data + t := getType(n.Sub[1].Sub[0]) + s, vs := modDefVars(n.Sub[2], t) + out := TVariable{tEnum, make(VarMap)} + for i := 0; i < len(s); i++ { + out.Data.(VarMap)[s[i]] = vs[i] + } + m.Defs[name] = out } // Parse a file and make an AST from it. @@ -69,6 +103,11 @@ func importFile(f string, m *TModule) { } } else if froot.Sub[n].Data.Data == "include" { importFile(evalPreLiteral(froot.Sub[n].Sub[0]), m) + } else if froot.Sub[n].Data.Data == "define" { + modDef(froot.Sub[n], m) + } else if froot.Sub[n].Data.Data == "enum"{ + modDefEnum(froot.Sub[n], m) + }else if froot.Sub[n].Data.Data == "struct" || froot.Sub[n].Data.Data == "raw"{ } else { m.Artifacts = append(m.Artifacts, froot.Sub[n]) } @@ -78,6 +117,7 @@ func importFile(f string, m *TModule) { // Build a module from a module block node func buildModule(module tparse.Node) TModule { out := TModule{} + out.Defs = make(VarMap) out.Name = module.Sub[0].Sub[0].Sub[0].Data.Data for n := 1 ; n < len(module.Sub) ; n++ { @@ -92,6 +132,7 @@ func buildModule(module tparse.Node) TModule { // BuildRoot builds the root module, ready for eval func BuildRoot(file string) TModule { out := TModule{} + out.Defs = make(VarMap) importFile(file, &out) diff --git a/src/tparse/tree-value.go b/src/tparse/tree-value.go index c44cdb6..1c7e99c 100644 --- a/src/tparse/tree-value.go +++ b/src/tparse/tree-value.go @@ -108,8 +108,8 @@ func parseUnaryOps(tokens *[]Token, tok, max int) (Node) { if vnode != &out { errOut("Composite values may not use unary operators.", out.Data) } - (*vnode) = Node{Token{10, "comp", 0, 0}, []Node{Node{}}} - (*vnode).Sub[0], tok = parseValueList(tokens, tok + 1, max) + (*vnode), tok = parseValueList(tokens, tok + 1, max) + (*vnode).Data.Data = "comp" val = true comp = true default: @@ -152,7 +152,7 @@ func parseUnaryOps(tokens *[]Token, tok, max int) (Node) { case "[": // Typecasting tmp, tok = parseTypeList(tokens, tok + 1, max) tmp.Data.Data = "cast" - case "{": // Array indexing + case "{": // Indexing if comp { errOut("Inline composite values can not be indexed.", t) } -- cgit v1.2.3