From dd6d1cc16c446fe017808b8ea1f7b88518466c01 Mon Sep 17 00:00:00 2001 From: Eduard Urbach Date: Thu, 30 Jan 2025 23:57:41 +0100 Subject: [PATCH] Implemented function pointers as parameters --- examples/thread/thread.q | 14 +++++----- src/asm/Finalize.go | 47 ++++++++++++++++++++++------------ src/core/ExpressionToMemory.go | 20 +++++++++++++-- src/core/TokenToRegister.go | 23 ++++++++++++----- tests/programs/param-order.q | 8 +++--- 5 files changed, 76 insertions(+), 36 deletions(-) diff --git a/examples/thread/thread.q b/examples/thread/thread.q index 09f0da6..3ef7e5e 100644 --- a/examples/thread/thread.q +++ b/examples/thread/thread.q @@ -2,18 +2,18 @@ import mem import sys main() { - start() - start() - start() + start(thread) + start(thread) + start(thread) thread() } -start() { +start(func Pointer) { size := 4096 stack := mem.alloc(size) - pointer := stack + size - 8 - store(pointer, 8, thread) - sys.clone(0x100 | 0x200 | 0x400 | 0x800 | 0x8000 | 0x10000 | 0x80000000, pointer) + rip := stack + size - 8 + store(rip, 8, func) + sys.clone(0x100|0x200|0x400|0x800|0x8000|0x10000|0x80000000, rip) } thread() { diff --git a/src/asm/Finalize.go b/src/asm/Finalize.go index 0f92006..688f377 100644 --- a/src/asm/Finalize.go +++ b/src/asm/Finalize.go @@ -225,24 +225,37 @@ func (a Assembler) Finalize(dlls dll.List) ([]byte, []byte) { opSize := len(code) - size - start regLabel := x.Data.(*RegisterLabel) - if !strings.HasPrefix(regLabel.Label, "data_") { - panic("non-data moves not implemented yet") + if strings.HasPrefix(regLabel.Label, "data_") { + dataPointers = append(dataPointers, &Pointer{ + Position: Address(len(code) - size), + OpSize: uint8(opSize), + Size: uint8(size), + Resolve: func() Address { + destination, exists := dataLabels[regLabel.Label] + + if !exists { + panic("unknown label") + } + + return Address(destination) + }, + }) + } else { + funcPointers = append(funcPointers, &Pointer{ + Position: Address(len(code) - size), + OpSize: uint8(opSize), + Size: uint8(size), + Resolve: func() Address { + destination, exists := codeLabels[regLabel.Label] + + if !exists { + panic("unknown label") + } + + return Address(destination) + }, + }) } - - dataPointers = append(dataPointers, &Pointer{ - Position: Address(len(code) - size), - OpSize: uint8(opSize), - Size: uint8(size), - Resolve: func() Address { - destination, exists := dataLabels[regLabel.Label] - - if !exists { - panic("unknown label") - } - - return Address(destination) - }, - }) } case NEGATE: diff --git a/src/core/ExpressionToMemory.go b/src/core/ExpressionToMemory.go index dfeb7da..bd84657 100644 --- a/src/core/ExpressionToMemory.go +++ b/src/core/ExpressionToMemory.go @@ -15,8 +15,24 @@ import ( func (f *Function) ExpressionToMemory(node *expression.Expression, memory asm.Memory) (*types.Type, error) { if node.IsLeaf() { if node.Token.Kind == token.Identifier { - f.MemoryLabel(asm.STORE, memory, fmt.Sprintf("%s.%s", f.Package, node.Token.Text(f.File.Bytes))) - return types.Pointer, nil + name := node.Token.Text(f.File.Bytes) + variable := f.VariableByName(name) + + if variable != nil { + f.UseVariable(variable) + f.MemoryRegister(asm.STORE, memory, variable.Register) + return types.Pointer, nil + } + + uniqueName := fmt.Sprintf("%s.%s", f.Package, name) + _, exists := f.Functions[uniqueName] + + if exists { + f.MemoryLabel(asm.STORE, memory, uniqueName) + return types.Pointer, nil + } + + return nil, errors.New(&errors.UnknownIdentifier{Name: name}, f.File, node.Token.Position) } if node.Token.IsNumeric() { diff --git a/src/core/TokenToRegister.go b/src/core/TokenToRegister.go index 117d8db..0b189e5 100644 --- a/src/core/TokenToRegister.go +++ b/src/core/TokenToRegister.go @@ -1,6 +1,8 @@ package core import ( + "fmt" + "git.akyoto.dev/cli/q/src/asm" "git.akyoto.dev/cli/q/src/cpu" "git.akyoto.dev/cli/q/src/errors" @@ -16,14 +18,23 @@ func (f *Function) TokenToRegister(t token.Token, register cpu.Register) (*types name := t.Text(f.File.Bytes) variable := f.VariableByName(name) - if variable == nil { - return nil, errors.New(&errors.UnknownIdentifier{Name: name}, f.File, t.Position) + if variable != nil { + f.UseVariable(variable) + f.SaveRegister(register) + f.RegisterRegister(asm.MOVE, register, variable.Register) + return variable.Type, nil } - f.UseVariable(variable) - f.SaveRegister(register) - f.RegisterRegister(asm.MOVE, register, variable.Register) - return variable.Type, nil + uniqueName := fmt.Sprintf("%s.%s", f.Package, name) + _, exists := f.Functions[uniqueName] + + if exists { + f.SaveRegister(register) + f.RegisterLabel(asm.MOVE, register, uniqueName) + return types.Pointer, nil + } + + return nil, errors.New(&errors.UnknownIdentifier{Name: name}, f.File, t.Position) case token.Number, token.Rune: number, err := f.Number(t) diff --git a/tests/programs/param-order.q b/tests/programs/param-order.q index 2b8ef0f..3e299b1 100644 --- a/tests/programs/param-order.q +++ b/tests/programs/param-order.q @@ -1,12 +1,12 @@ main() { - f(1, 2, 3, 4, 5, 6) + f1(1, 2, 3, 4, 5, 6) } -f(a Int, b Int, c Int, d Int, e Int, f Int) { - g(f, e, d, c, b, a) +f1(a Int, b Int, c Int, d Int, e Int, f Int) { + f2(f, e, d, c, b, a) } -g(a Int, b Int, c Int, d Int, e Int, f Int) { +f2(a Int, b Int, c Int, d Int, e Int, f Int) { assert a == 6 assert b == 5 assert c == 4