Implemented type checks
This commit is contained in:
parent
baa2463b4b
commit
cacee7260a
19 changed files with 199 additions and 79 deletions
|
@ -15,80 +15,80 @@ import (
|
|||
func (f *Function) CompileCall(root *expression.Expression) (*Function, error) {
|
||||
var (
|
||||
pkg = f.Package
|
||||
nameRoot = root.Children[0]
|
||||
nameNode = root.Children[0]
|
||||
fn *Function
|
||||
name string
|
||||
fullName string
|
||||
exists bool
|
||||
)
|
||||
|
||||
if nameRoot.IsLeaf() {
|
||||
name = nameRoot.Token.Text(f.File.Bytes)
|
||||
if nameNode.IsLeaf() {
|
||||
name = nameNode.Token.Text(f.File.Bytes)
|
||||
|
||||
if name == "syscall" {
|
||||
return nil, f.CompileSyscall(root)
|
||||
}
|
||||
} else {
|
||||
pkg = nameRoot.Children[0].Token.Text(f.File.Bytes)
|
||||
name = nameRoot.Children[1].Token.Text(f.File.Bytes)
|
||||
pkg = nameNode.Children[0].Token.Text(f.File.Bytes)
|
||||
name = nameNode.Children[1].Token.Text(f.File.Bytes)
|
||||
}
|
||||
|
||||
isSyscall := name == "syscall"
|
||||
|
||||
if !isSyscall {
|
||||
if pkg != f.File.Package {
|
||||
if f.File.Imports == nil {
|
||||
return nil, errors.New(&errors.UnknownPackage{Name: pkg}, f.File, nameRoot.Token.Position)
|
||||
}
|
||||
|
||||
imp, exists := f.File.Imports[pkg]
|
||||
|
||||
if !exists {
|
||||
return nil, errors.New(&errors.UnknownPackage{Name: pkg}, f.File, nameRoot.Token.Position)
|
||||
}
|
||||
|
||||
imp.Used = true
|
||||
if pkg != f.File.Package {
|
||||
if f.File.Imports == nil {
|
||||
return nil, errors.New(&errors.UnknownPackage{Name: pkg}, f.File, nameNode.Token.Position)
|
||||
}
|
||||
|
||||
tmp := strings.Builder{}
|
||||
tmp.WriteString(pkg)
|
||||
tmp.WriteString(".")
|
||||
tmp.WriteString(name)
|
||||
fullName = tmp.String()
|
||||
fn, exists = f.Functions[fullName]
|
||||
imp, exists := f.File.Imports[pkg]
|
||||
|
||||
if !exists {
|
||||
return nil, errors.New(&errors.UnknownFunction{Name: name}, f.File, nameRoot.Token.Position)
|
||||
return nil, errors.New(&errors.UnknownPackage{Name: pkg}, f.File, nameNode.Token.Position)
|
||||
}
|
||||
|
||||
imp.Used = true
|
||||
}
|
||||
|
||||
tmp := strings.Builder{}
|
||||
tmp.WriteString(pkg)
|
||||
tmp.WriteString(".")
|
||||
tmp.WriteString(name)
|
||||
fullName = tmp.String()
|
||||
fn, exists = f.Functions[fullName]
|
||||
|
||||
if !exists {
|
||||
return nil, errors.New(&errors.UnknownFunction{Name: name}, f.File, nameNode.Token.Position)
|
||||
}
|
||||
|
||||
parameters := root.Children[1:]
|
||||
registers := f.CPU.Input[:len(parameters)]
|
||||
|
||||
if isSyscall {
|
||||
registers = f.CPU.Syscall[:len(parameters)]
|
||||
for i := len(parameters) - 1; i >= 0; i-- {
|
||||
typ, err := f.ExpressionToRegister(parameters[i], registers[i])
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if typ != fn.Parameters[i].Type {
|
||||
return nil, errors.New(&errors.TypeMismatch{
|
||||
Encountered: string(typ),
|
||||
Expected: string(fn.Parameters[i].Type),
|
||||
ParameterName: fn.Parameters[i].Name,
|
||||
}, f.File, parameters[i].Token.Position)
|
||||
}
|
||||
}
|
||||
|
||||
err := f.ExpressionsToRegisters(parameters, registers)
|
||||
|
||||
if err != nil {
|
||||
return fn, err
|
||||
for _, register := range f.CPU.Output[:len(fn.ReturnTypes)] {
|
||||
f.SaveRegister(register)
|
||||
}
|
||||
|
||||
// TODO: Save all return value registers of the function
|
||||
f.SaveRegister(f.CPU.Output[0])
|
||||
|
||||
// Push
|
||||
for _, register := range f.CPU.General {
|
||||
if f.RegisterIsUsed(register) {
|
||||
f.Register(asm.PUSH, register)
|
||||
}
|
||||
}
|
||||
|
||||
// Call
|
||||
if isSyscall {
|
||||
f.Syscall()
|
||||
} else {
|
||||
f.Call(fullName)
|
||||
}
|
||||
f.Call(fullName)
|
||||
|
||||
// Free parameter registers
|
||||
for _, register := range registers {
|
||||
if register == f.CPU.Output[0] && root.Parent != nil {
|
||||
continue
|
||||
|
@ -97,7 +97,6 @@ func (f *Function) CompileCall(root *expression.Expression) (*Function, error) {
|
|||
f.FreeRegister(register)
|
||||
}
|
||||
|
||||
// Pop
|
||||
for i := len(f.CPU.General) - 1; i >= 0; i-- {
|
||||
register := f.CPU.General[i]
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue