Added placeholders for type casts
This commit is contained in:
parent
bbf2970c4e
commit
ae6530aadb
@ -1,6 +1,3 @@
|
||||
// Open server and client in 2 terminals:
|
||||
// [1] q run examples/server
|
||||
// [2] curl http://127.0.0.1:8080
|
||||
import io
|
||||
import net
|
||||
import sys
|
||||
|
@ -1,6 +1,6 @@
|
||||
import sys
|
||||
|
||||
bind(socket int, port int) -> int {
|
||||
bind(socket int, port uint16) -> int {
|
||||
addr := new(sys.sockaddr_in)
|
||||
addr.sin_family = 2
|
||||
addr.sin_port = htons(port)
|
||||
|
@ -1,12 +1,12 @@
|
||||
read(fd int64, buffer *byte, length int64) -> int64 {
|
||||
read(fd int, buffer *byte, length int) -> int {
|
||||
fd = kernel32.GetStdHandle(-10 - fd)
|
||||
kernel32.ReadConsole(fd, buffer, length, 0)
|
||||
kernel32.ReadConsole(fd, buffer, uint32(length), 0)
|
||||
return length
|
||||
}
|
||||
|
||||
write(fd int64, buffer *byte, length int64) -> int64 {
|
||||
write(fd int, buffer *byte, length int) -> int {
|
||||
fd = kernel32.GetStdHandle(-10 - fd)
|
||||
kernel32.WriteConsoleA(fd, buffer, length, 0)
|
||||
kernel32.WriteConsoleA(fd, buffer, uint32(length), 0)
|
||||
return length
|
||||
}
|
||||
|
||||
|
@ -12,10 +12,8 @@ const clone {
|
||||
}
|
||||
|
||||
create(func *any) -> int {
|
||||
size := 4096
|
||||
stack := sys.mmap(0, size, 0x1|0x2, 0x02|0x20|0x100|0x20000)
|
||||
stack += size
|
||||
stack -= 8
|
||||
stack := sys.mmap(0, 4096, 0x1|0x2, 0x02|0x20|0x100)
|
||||
stack += 4096 - 8
|
||||
store(stack, 8, core.exit)
|
||||
stack -= 8
|
||||
store(stack, 8, func)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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() {
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
Int = Int64
|
||||
UInt = UInt64
|
||||
)
|
||||
|
@ -25,13 +25,11 @@ func Is(a Type, b Type) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// Temporary hacks
|
||||
if a == Int32 && b == Int64 {
|
||||
if a == AnyInt {
|
||||
switch b {
|
||||
case Int64, Int32, Int16, Int8, UInt64, UInt32, UInt16, UInt8:
|
||||
return true
|
||||
}
|
||||
|
||||
if a == Int64 && b == Int32 {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
|
@ -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) {
|
||||
|
@ -50,8 +50,8 @@ var errs = []struct {
|
||||
{"MissingParameter3.q", errors.MissingParameter},
|
||||
{"MissingType.q", errors.MissingType},
|
||||
{"ReturnCountMismatch.q", &errors.ReturnCountMismatch{Count: 1, ExpectedCount: 0}},
|
||||
{"TypeMismatch.q", &errors.TypeMismatch{Expected: "*any", Encountered: "int64", ParameterName: "p"}},
|
||||
{"TypeMismatch2.q", &errors.TypeMismatch{Expected: "[]any", Encountered: "int64", ParameterName: "array"}},
|
||||
{"TypeMismatch.q", &errors.TypeMismatch{Expected: "*any", Encountered: "int", ParameterName: "p"}},
|
||||
{"TypeMismatch2.q", &errors.TypeMismatch{Expected: "[]any", Encountered: "int", ParameterName: "array"}},
|
||||
{"UnknownFunction.q", &errors.UnknownFunction{Name: "unknown"}},
|
||||
{"UnknownFunction2.q", &errors.UnknownFunction{Name: "f"}},
|
||||
{"UnknownIdentifier.q", &errors.UnknownIdentifier{Name: "x"}},
|
||||
|
8
tests/programs/cast.q
Normal file
8
tests/programs/cast.q
Normal file
@ -0,0 +1,8 @@
|
||||
main() {
|
||||
x := byte(42)
|
||||
assert f(x) == 42
|
||||
}
|
||||
|
||||
f(x byte) -> byte {
|
||||
return x
|
||||
}
|
@ -67,6 +67,7 @@ var programs = []struct {
|
||||
{"index-dynamic", 0},
|
||||
{"struct", 0},
|
||||
{"len", 0},
|
||||
{"cast", 0},
|
||||
}
|
||||
|
||||
func TestPrograms(t *testing.T) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user