begin separating types into lang vs vm

This commit is contained in:
Brian Picciano 2017-02-12 09:53:59 -07:00
parent a5040a6248
commit 4180e6b072
4 changed files with 52 additions and 9 deletions

View File

@ -13,6 +13,5 @@ var (
TDblUnder = Tuple{AUnder, AUnder}
// VM commands
AInt = Atom("int")
AAdd = Atom("add")
)

View File

@ -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)

View File

@ -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
},
},

44
vm/types.go Normal file
View File

@ -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)
}
}