45 lines
917 B
Go
45 lines
917 B
Go
|
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)
|
||
|
}
|
||
|
}
|