Added placeholders for type casts

This commit is contained in:
2025-02-27 00:18:34 +01:00
parent bbf2970c4e
commit ae6530aadb
19 changed files with 61 additions and 42 deletions

View File

@ -50,8 +50,8 @@ func (f *Function) ArrayElementToRegister(node *expression.Expression, register
defer f.UseVariable(indexVariable)
if !types.Is(indexVariable.Type, types.Int) {
return nil, errors.New(&errors.TypeMismatch{Encountered: indexVariable.Type.Name(), Expected: types.Int.Name()}, f.File, index.Token.Position)
if !types.Is(indexVariable.Type, types.AnyInt) {
return nil, errors.New(&errors.TypeMismatch{Encountered: indexVariable.Type.Name(), Expected: types.AnyInt.Name()}, f.File, index.Token.Position)
}
memory.OffsetRegister = indexVariable.Register
@ -63,8 +63,8 @@ func (f *Function) ArrayElementToRegister(node *expression.Expression, register
return nil, err
}
if !types.Is(typ, types.Int) {
return nil, errors.New(&errors.TypeMismatch{Encountered: typ.Name(), Expected: types.Int.Name()}, f.File, index.Token.Position)
if !types.Is(typ, types.AnyInt) {
return nil, errors.New(&errors.TypeMismatch{Encountered: typ.Name(), Expected: types.AnyInt.Name()}, f.File, index.Token.Position)
}
memory.OffsetRegister = register

View File

@ -47,8 +47,8 @@ func (f *Function) CompileAssignArray(node *ast.Assign) error {
return err
}
if !types.Is(typ, types.Int) {
return errors.New(&errors.TypeMismatch{Encountered: typ.Name(), Expected: types.Int.Name()}, f.File, index.Token.Position)
if !types.Is(typ, types.AnyInt) {
return errors.New(&errors.TypeMismatch{Encountered: typ.Name(), Expected: types.AnyInt.Name()}, f.File, index.Token.Position)
}
memory.OffsetRegister = indexRegister

View File

@ -52,6 +52,17 @@ func (f *Function) CompileCall(root *expression.Expression) ([]types.Type, error
fn, exists = f.All.Functions[pkg+"."+name]
if !exists {
typ := types.ByName(name, f.Package, f.All.Structs)
if typ != nil {
if len(root.Children) != 2 {
return nil, errors.New(&errors.ParameterCountMismatch{Function: name, Count: len(root.Children), ExpectedCount: 1}, f.File, nameNode.Token.End())
}
_, err := f.ExpressionToRegister(root.Children[1], f.CPU.Output[0])
return []types.Type{typ}, err
}
return nil, errors.New(&errors.UnknownFunction{Name: name}, f.File, nameNode.Token.Position)
}

View File

@ -6,6 +6,7 @@ import (
"git.urbach.dev/cli/q/src/errors"
"git.urbach.dev/cli/q/src/expression"
"git.urbach.dev/cli/q/src/token"
"git.urbach.dev/cli/q/src/types"
)
// CompileDefinition compiles a variable definition.
@ -30,6 +31,10 @@ func (f *Function) CompileDefinition(node *ast.Define) error {
return errors.New(errors.UntypedExpression, f.File, node.Expression.Token.End())
}
if typ == types.AnyInt {
typ = types.Int
}
variable.Type = typ
f.AddVariable(variable)
return nil

View File

@ -9,7 +9,7 @@ import (
"git.urbach.dev/cli/q/src/types"
)
var _len = Function{OutputTypes: []types.Type{types.Int}}
var _len = Function{OutputTypes: []types.Type{types.AnyInt}}
// CompileLen returns the length of a slice.
func (f *Function) CompileLen(root *expression.Expression) error {

View File

@ -48,7 +48,7 @@ func (f *Function) ExpressionToMemory(node *expression.Expression, memory asm.Me
// }
f.MemoryNumber(asm.STORE, memory, number)
return types.Int, nil
return types.AnyInt, nil
}
}

View File

@ -13,7 +13,7 @@ import (
func (f *Function) ExpressionToRegister(node *expression.Expression, register cpu.Register) (types.Type, error) {
if node.IsFolded {
f.RegisterNumber(asm.MOVE, register, node.Value)
return types.Int, nil
return types.AnyInt, nil
}
if node.IsLeaf() {

View File

@ -14,8 +14,8 @@ import (
// PeriodToRegister moves a constant or a function address into the given register.
func (f *Function) PeriodToRegister(node *expression.Expression, register cpu.Register) (types.Type, error) {
left := node.Children[0]
leftText := left.Token.Text(f.File.Bytes)
right := node.Children[1]
leftText := left.Token.Text(f.File.Bytes)
rightText := right.Token.Text(f.File.Bytes)
variable := f.VariableByName(leftText)
@ -44,7 +44,7 @@ func (f *Function) PeriodToRegister(node *expression.Expression, register cpu.Re
f.SaveRegister(register)
f.RegisterNumber(asm.MOVE, register, number)
return types.Int, nil
return types.AnyInt, nil
}
uniqueName := fmt.Sprintf("%s.%s", leftText, rightText)

View File

@ -53,7 +53,7 @@ func (f *Function) TokenToRegister(t token.Token, register cpu.Register) (types.
f.SaveRegister(register)
f.RegisterNumber(asm.MOVE, register, number)
return types.Int, nil
return types.AnyInt, nil
case token.String:
data := t.Bytes(f.File.Bytes)

View File

@ -3,6 +3,7 @@ package types
var (
Any = &Base{name: "any", size: 0}
AnyArray = &Array{Of: Any}
AnyInt = &Base{name: "int"}
AnyPointer = &Pointer{To: Any}
Bool = &Base{name: "bool", size: 1}
Int64 = &Base{name: "int64", size: 8}
@ -12,15 +13,15 @@ var (
Float64 = &Base{name: "float64", size: 8}
Float32 = &Base{name: "float32", size: 4}
String = &Array{Of: Byte}
UInt64 = &Base{name: "uint64", size: 8}
UInt32 = &Base{name: "uint32", size: 4}
UInt16 = &Base{name: "uint16", size: 2}
UInt8 = &Base{name: "uint8", size: 1}
)
var (
Byte = UInt8
Int = Int64
Float = Float64
UInt = Int
UInt64 = Int64
UInt32 = Int32
UInt16 = Int16
UInt8 = Int8
Byte = UInt8
Float = Float64
Int = Int64
UInt = UInt64
)

View File

@ -25,13 +25,11 @@ func Is(a Type, b Type) bool {
return true
}
// Temporary hacks
if a == Int32 && b == Int64 {
return true
}
if a == Int64 && b == Int32 {
return true
if a == AnyInt {
switch b {
case Int64, Int32, Int16, Int8, UInt64, UInt32, UInt16, UInt8:
return true
}
}
return false

View File

@ -13,7 +13,7 @@ func TestName(t *testing.T) {
assert.Equal(t, types.AnyPointer.Name(), "*any")
assert.Equal(t, (&types.Pointer{To: types.Int}).Name(), "*int64")
assert.Equal(t, (&types.Array{Of: types.Int}).Name(), "[]int64")
assert.Equal(t, types.String.Name(), "[]int8")
assert.Equal(t, types.String.Name(), "[]uint8")
}
func TestSize(t *testing.T) {