Added array type
This commit is contained in:
parent
c69f1aab5c
commit
7634244c56
10
lib/io/io.q
10
lib/io/io.q
@ -1,21 +1,21 @@
|
||||
import sys
|
||||
|
||||
in(buffer Pointer) -> Int {
|
||||
in(buffer []Int8) -> Int {
|
||||
return sys.read(0, buffer, len(buffer))
|
||||
}
|
||||
|
||||
out(message Pointer) -> Int {
|
||||
out(message []Int8) -> Int {
|
||||
return sys.write(1, message, len(message))
|
||||
}
|
||||
|
||||
error(message Pointer) -> Int {
|
||||
error(message []Int8) -> Int {
|
||||
return sys.write(2, message, len(message))
|
||||
}
|
||||
|
||||
read(fd Int, buffer Pointer) -> Int {
|
||||
read(fd Int, buffer []Int8) -> Int {
|
||||
return sys.read(fd, buffer, len(buffer))
|
||||
}
|
||||
|
||||
write(fd Int, message Pointer) -> Int {
|
||||
write(fd Int, message []Int8) -> Int {
|
||||
return sys.write(fd, message, len(message))
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
import sys
|
||||
|
||||
alloc(length Int) -> Pointer {
|
||||
alloc(length Int) -> []Int8 {
|
||||
x := sys.mmap(0, length+8, 0x1|0x2, 0x02|0x20)
|
||||
|
||||
if x < 0x1000 {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import sys
|
||||
|
||||
alloc(length Int) -> Pointer {
|
||||
alloc(length Int) -> []Int8 {
|
||||
x := sys.mmap(0, length+8, 0x1|0x2, 0x02|0x1000)
|
||||
|
||||
if x < 0x1000 {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import sys
|
||||
|
||||
alloc(length Int) -> Pointer {
|
||||
alloc(length Int) -> []Int8 {
|
||||
x := sys.mmap(0, length+8, 0x0004, 0x3000)
|
||||
|
||||
if x < 0x1000 {
|
||||
|
@ -26,6 +26,10 @@ func (f *Function) CompileReturn(node *ast.Return) error {
|
||||
}
|
||||
|
||||
if !types.Is(typ, f.Output[i].Type) {
|
||||
if f.Package == "mem" && f.Name == "alloc" {
|
||||
return nil
|
||||
}
|
||||
|
||||
return errors.New(&errors.TypeMismatch{
|
||||
Encountered: typ.Name(),
|
||||
Expected: f.Output[i].Type.Name(),
|
||||
|
@ -18,12 +18,12 @@ func (f *Function) ExpressionToMemory(node *expression.Expression, memory asm.Me
|
||||
if variable != nil {
|
||||
f.MemoryRegister(asm.STORE, memory, variable.Register)
|
||||
f.UseVariable(variable)
|
||||
return types.PointerAny, nil
|
||||
return types.AnyPointer, nil
|
||||
}
|
||||
|
||||
if function != nil {
|
||||
f.MemoryLabel(asm.STORE, memory, function.UniqueName)
|
||||
return types.PointerAny, nil
|
||||
return types.AnyPointer, nil
|
||||
}
|
||||
|
||||
return nil, errors.New(&errors.UnknownIdentifier{Name: name}, f.File, node.Token.Position)
|
||||
|
@ -83,7 +83,7 @@ func (f *Function) ExpressionToRegister(node *expression.Expression, register cp
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if typ == types.PointerAny && right.Token.Kind == token.Identifier && f.VariableByName(right.Token.Text(f.File.Bytes)).Type == types.PointerAny {
|
||||
if typ == types.AnyPointer && right.Token.Kind == token.Identifier && f.VariableByName(right.Token.Text(f.File.Bytes)).Type == types.AnyPointer {
|
||||
typ = types.Int
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@ func (f *Function) TokenToRegister(t token.Token, register cpu.Register) (types.
|
||||
if function != nil {
|
||||
f.SaveRegister(register)
|
||||
f.RegisterLabel(asm.MOVE, register, function.UniqueName)
|
||||
return types.PointerAny, nil
|
||||
return types.AnyPointer, nil
|
||||
}
|
||||
|
||||
return nil, errors.New(&errors.UnknownIdentifier{Name: name}, f.File, t.Position)
|
||||
@ -55,7 +55,7 @@ func (f *Function) TokenToRegister(t token.Token, register cpu.Register) (types.
|
||||
label := f.AddBytes(slice)
|
||||
f.SaveRegister(register)
|
||||
f.RegisterLabel(asm.MOVE, register, label)
|
||||
return types.PointerAny, nil
|
||||
return types.String, nil
|
||||
|
||||
default:
|
||||
return nil, errors.New(errors.InvalidExpression, f.File, t.Position)
|
||||
|
18
src/types/Array.go
Normal file
18
src/types/Array.go
Normal file
@ -0,0 +1,18 @@
|
||||
package types
|
||||
|
||||
var String = &Array{Of: Int8}
|
||||
|
||||
// Array is the address of an object.
|
||||
type Array struct {
|
||||
Of Type
|
||||
}
|
||||
|
||||
// Name returns the type name.
|
||||
func (a *Array) Name() string {
|
||||
return "[]" + a.Of.Name()
|
||||
}
|
||||
|
||||
// Size returns the total size in bytes.
|
||||
func (a *Array) Size() int {
|
||||
return 8
|
||||
}
|
@ -17,6 +17,17 @@ func ByName(name string, pkg string, structs map[string]*Struct) Type {
|
||||
return nil
|
||||
}
|
||||
|
||||
if strings.HasPrefix(name, "[]") {
|
||||
to := strings.TrimPrefix(name, "[]")
|
||||
typ := ByName(to, pkg, structs)
|
||||
|
||||
if typ != nil {
|
||||
return &Array{Of: typ}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
switch name {
|
||||
case "Int":
|
||||
return Int
|
||||
@ -35,7 +46,7 @@ func ByName(name string, pkg string, structs map[string]*Struct) Type {
|
||||
case "Float32":
|
||||
return Float32
|
||||
case "Pointer":
|
||||
return PointerAny
|
||||
return AnyPointer
|
||||
}
|
||||
|
||||
typ, exists := structs[pkg+"."+name]
|
||||
|
@ -17,5 +17,17 @@ func Is(a Type, b Type) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
aArray, aIsArray := a.(*Array)
|
||||
|
||||
if aIsArray && bIsPointer && (bPointer.To == nil || aArray.Of == bPointer.To) {
|
||||
return true
|
||||
}
|
||||
|
||||
bArray, bIsArray := b.(*Array)
|
||||
|
||||
if aIsArray && bIsArray && aArray.Of == bArray.Of {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
package types
|
||||
|
||||
var PointerAny = &Pointer{To: nil}
|
||||
var AnyPointer = &Pointer{To: nil}
|
||||
|
||||
// Pointer is the address of an object.
|
||||
type Pointer struct {
|
||||
@ -13,7 +13,7 @@ func (p *Pointer) Name() string {
|
||||
return "Pointer"
|
||||
}
|
||||
|
||||
return "Pointer:" + p.To.Name()
|
||||
return "*" + p.To.Name()
|
||||
}
|
||||
|
||||
// Size returns the total size in bytes.
|
||||
|
@ -9,8 +9,10 @@ import (
|
||||
|
||||
func TestName(t *testing.T) {
|
||||
assert.Equal(t, types.Int.Name(), "Int64")
|
||||
assert.Equal(t, types.PointerAny.Name(), "Pointer")
|
||||
assert.Equal(t, (&types.Pointer{To: types.Int}).Name(), "Pointer:Int64")
|
||||
assert.Equal(t, types.AnyPointer.Name(), "Pointer")
|
||||
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")
|
||||
}
|
||||
|
||||
func TestSize(t *testing.T) {
|
||||
@ -19,7 +21,8 @@ func TestSize(t *testing.T) {
|
||||
assert.Equal(t, types.Int16.Size(), 2)
|
||||
assert.Equal(t, types.Int32.Size(), 4)
|
||||
assert.Equal(t, types.Int64.Size(), 8)
|
||||
assert.Equal(t, types.PointerAny.Size(), 8)
|
||||
assert.Equal(t, types.AnyPointer.Size(), 8)
|
||||
assert.Equal(t, types.String.Size(), 8)
|
||||
assert.Equal(t, (&types.Pointer{To: types.Int}).Size(), 8)
|
||||
}
|
||||
|
||||
@ -37,7 +40,7 @@ func TestStruct(t *testing.T) {
|
||||
|
||||
func TestBasics(t *testing.T) {
|
||||
assert.True(t, types.Is(types.Int, types.Int))
|
||||
assert.True(t, types.Is(types.PointerAny, types.PointerAny))
|
||||
assert.True(t, types.Is(types.AnyPointer, types.AnyPointer))
|
||||
assert.False(t, types.Is(types.Int, types.Float))
|
||||
assert.False(t, types.Is(&types.Pointer{To: types.Int}, &types.Pointer{To: types.Float}))
|
||||
}
|
||||
@ -50,6 +53,7 @@ func TestSpecialCases(t *testing.T) {
|
||||
|
||||
// Case #2:
|
||||
// A pointer pointing to a known type fulfills the requirement of a pointer to anything.
|
||||
assert.True(t, types.Is(&types.Pointer{To: types.Int}, &types.Pointer{To: nil}))
|
||||
assert.True(t, types.Is(&types.Pointer{To: types.Float}, &types.Pointer{To: nil}))
|
||||
assert.True(t, types.Is(&types.Pointer{To: types.Int}, types.AnyPointer))
|
||||
assert.True(t, types.Is(&types.Pointer{To: types.Float}, types.AnyPointer))
|
||||
assert.True(t, types.Is(&types.Array{Of: types.Int}, types.AnyPointer))
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user