From 4180e6b072fe6cdc8d094fa5df68183f6d261ac5 Mon Sep 17 00:00:00 2001 From: Brian Picciano Date: Sun, 12 Feb 2017 09:53:59 -0700 Subject: [PATCH] begin separating types into lang vs vm --- lang/common.go | 1 - main.go | 4 ++-- vm/cmds.go | 12 ++++++------ vm/types.go | 44 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 52 insertions(+), 9 deletions(-) create mode 100644 vm/types.go diff --git a/lang/common.go b/lang/common.go index 5cffd60..30a6d4f 100644 --- a/lang/common.go +++ b/lang/common.go @@ -13,6 +13,5 @@ var ( TDblUnder = Tuple{AUnder, AUnder} // VM commands - AInt = Atom("int") AAdd = Atom("add") ) diff --git a/main.go b/main.go index 1a7b5db..16e3e02 100644 --- a/main.go +++ b/main.go @@ -9,8 +9,8 @@ import ( func main() { t := lang.Tuple{lang.AAdd, lang.Tuple{ - lang.Tuple{lang.AInt, lang.Const("1")}, - lang.Tuple{lang.AInt, lang.Const("2")}, + lang.Tuple{vm.Int, lang.Const("1")}, + lang.Tuple{vm.Int, lang.Const("2")}, }} mod, err := vm.Build(t) diff --git a/vm/cmds.go b/vm/cmds.go index 20cf6a8..9807fa5 100644 --- a/vm/cmds.go +++ b/vm/cmds.go @@ -44,14 +44,14 @@ func buildCmds(mod *Module) []buildCmd { return lang.Tuple{lang.AConst, t} } tPat := func(el ...lang.Term) lang.Tuple { - return lang.Tuple{lang.ATuple, lang.Tuple(el)} + return lang.Tuple{Tuple, lang.Tuple(el)} } buildPat := func(a lang.Atom, b lang.Tuple) lang.Tuple { return tPat(aPat(a), b) } return []buildCmd{ { // (int 42) - pattern: buildPat(lang.AInt, cPat(lang.AUnder)), + pattern: buildPat(Int, cPat(lang.AUnder)), outTypeFn: func(t lang.Term) (llvm.Type, error) { return llvm.Int64Type(), nil }, @@ -64,13 +64,13 @@ func buildCmds(mod *Module) []buildCmd { return val{ // TODO why does this have to be cast? v: llvm.ConstInt(llvm.Int64Type(), uint64(coni), false), - typ: lang.AInt, + typ: Int, }, nil }, }, { // (tup ((atom foo) (const 10))) - pattern: buildPat(lang.ATuple, lang.Tuple{lang.ATuple, lang.AUnder}), + pattern: buildPat(Tuple, lang.Tuple{Tuple, lang.AUnder}), outTypeFn: func(t lang.Term) (llvm.Type, error) { tup := t.(lang.Tuple) if len(tup) == 0 { @@ -91,7 +91,7 @@ func buildCmds(mod *Module) []buildCmd { if len(tup) == 0 { return val{ v: llvm.Undef(llvm.VoidType()), - typ: lang.Tuple{lang.ATuple, lang.Tuple{}}, + typ: lang.Tuple{Tuple, lang.Tuple{}}, }, nil } @@ -113,7 +113,7 @@ func buildCmds(mod *Module) []buildCmd { } return val{ v: str, - typ: lang.Tuple{lang.ATuple, lang.Tuple(ttyps)}, + typ: lang.Tuple{Tuple, lang.Tuple(ttyps)}, }, nil }, }, diff --git a/vm/types.go b/vm/types.go new file mode 100644 index 0000000..4b2d8e0 --- /dev/null +++ b/vm/types.go @@ -0,0 +1,44 @@ +package vm + +import ( + "fmt" + + "github.com/mediocregopher/ginger/lang" + "llvm.org/llvm/bindings/go/llvm" +) + +// Types supported by the vm in addition to those which are part of lang +var ( + Atom = lang.AAtom + Tuple = lang.ATuple + Int = lang.Atom("int") +) + +var ( + tupPat = lang.Tuple{lang.ATuple, lang.Tuple{ + lang.Tuple{lang.AAtom, Tuple}, + lang.Tuple{lang.ATuple, lang.AUnder}, + }} +) + +func termToType(t lang.Term) (llvm.Type, error) { + switch { + case lang.Equal(t, Int): + return llvm.Int64Type(), nil + case lang.Match(tupPat, t): + tup := t.(lang.Tuple)[1].(lang.Tuple) + if len(tup) == 0 { + return llvm.VoidType(), nil + } + var err error + typs := make([]llvm.Type, len(tup)) + for i := range tup { + if typs[i], err = termToType(tup[i]); err != nil { + return llvm.Type{}, err + } + } + return llvm.StructType(typs, false), nil + default: + return llvm.Type{}, fmt.Errorf("type %v not supported", t) + } +}