Added array type

This commit is contained in:
Eduard Urbach 2025-02-09 20:25:37 +01:00
parent c69f1aab5c
commit 7634244c56
Signed by: akyoto
GPG Key ID: C874F672B1AF20C0
13 changed files with 71 additions and 22 deletions

View File

@ -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))
}

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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(),

View File

@ -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)

View File

@ -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
}

View File

@ -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
View 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
}

View File

@ -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]

View File

@ -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
}

View File

@ -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.

View File

@ -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))
}