Implemented function pointers as parameters

This commit is contained in:
Eduard Urbach 2025-01-30 23:57:41 +01:00
parent 313302b9c8
commit dd6d1cc16c
Signed by: akyoto
GPG Key ID: C874F672B1AF20C0
5 changed files with 76 additions and 36 deletions

View File

@ -2,18 +2,18 @@ import mem
import sys import sys
main() { main() {
start() start(thread)
start() start(thread)
start() start(thread)
thread() thread()
} }
start() { start(func Pointer) {
size := 4096 size := 4096
stack := mem.alloc(size) stack := mem.alloc(size)
pointer := stack + size - 8 rip := stack + size - 8
store(pointer, 8, thread) store(rip, 8, func)
sys.clone(0x100 | 0x200 | 0x400 | 0x800 | 0x8000 | 0x10000 | 0x80000000, pointer) sys.clone(0x100|0x200|0x400|0x800|0x8000|0x10000|0x80000000, rip)
} }
thread() { thread() {

View File

@ -225,24 +225,37 @@ func (a Assembler) Finalize(dlls dll.List) ([]byte, []byte) {
opSize := len(code) - size - start opSize := len(code) - size - start
regLabel := x.Data.(*RegisterLabel) regLabel := x.Data.(*RegisterLabel)
if !strings.HasPrefix(regLabel.Label, "data_") { if strings.HasPrefix(regLabel.Label, "data_") {
panic("non-data moves not implemented yet") 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: case NEGATE:

View File

@ -15,8 +15,24 @@ import (
func (f *Function) ExpressionToMemory(node *expression.Expression, memory asm.Memory) (*types.Type, error) { func (f *Function) ExpressionToMemory(node *expression.Expression, memory asm.Memory) (*types.Type, error) {
if node.IsLeaf() { if node.IsLeaf() {
if node.Token.Kind == token.Identifier { if node.Token.Kind == token.Identifier {
f.MemoryLabel(asm.STORE, memory, fmt.Sprintf("%s.%s", f.Package, node.Token.Text(f.File.Bytes))) name := node.Token.Text(f.File.Bytes)
return types.Pointer, nil 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() { if node.Token.IsNumeric() {

View File

@ -1,6 +1,8 @@
package core package core
import ( import (
"fmt"
"git.akyoto.dev/cli/q/src/asm" "git.akyoto.dev/cli/q/src/asm"
"git.akyoto.dev/cli/q/src/cpu" "git.akyoto.dev/cli/q/src/cpu"
"git.akyoto.dev/cli/q/src/errors" "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) name := t.Text(f.File.Bytes)
variable := f.VariableByName(name) variable := f.VariableByName(name)
if variable == nil { if variable != nil {
return nil, errors.New(&errors.UnknownIdentifier{Name: name}, f.File, t.Position) f.UseVariable(variable)
f.SaveRegister(register)
f.RegisterRegister(asm.MOVE, register, variable.Register)
return variable.Type, nil
} }
f.UseVariable(variable) uniqueName := fmt.Sprintf("%s.%s", f.Package, name)
f.SaveRegister(register) _, exists := f.Functions[uniqueName]
f.RegisterRegister(asm.MOVE, register, variable.Register)
return variable.Type, nil 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: case token.Number, token.Rune:
number, err := f.Number(t) number, err := f.Number(t)

View File

@ -1,12 +1,12 @@
main() { 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) { f1(a Int, b Int, c Int, d Int, e Int, f Int) {
g(f, e, d, c, b, a) 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 a == 6
assert b == 5 assert b == 5
assert c == 4 assert c == 4