Implemented parameters

This commit is contained in:
Eduard Urbach 2024-06-27 10:12:41 +02:00
parent 94151773a5
commit 8e64271f74
Signed by: akyoto
GPG Key ID: C874F672B1AF20C0
6 changed files with 76 additions and 27 deletions

View File

@ -3,18 +3,13 @@ main() {
}
hello() {
write := 1
stdout := 1
address := 0
length := 0
address += 4194304
address += 1
length = 0 + 1
length -= length
length += write + stdout
length -= length
length = address - address
length += 50
length -= 20
length *= 10
@ -22,6 +17,14 @@ hello() {
length = (0 + 50 - 20) * 10 / 100
loop {
syscall(write, stdout, address, length)
print(address, length)
}
}
print(address, length) {
write(1, address, length)
}
write(fd, address, length) {
syscall(1, fd, address, length)
}

View File

@ -101,7 +101,9 @@ func (f *Function) ExecuteRegisterRegister(operation token.Token, destination cp
f.Assembler.RegisterRegister(asm.DIV, destination, source)
case "=":
f.Assembler.RegisterRegister(asm.MOVE, destination, source)
if destination != source {
f.Assembler.RegisterRegister(asm.MOVE, destination, source)
}
default:
return errors.New(&errors.InvalidOperator{Operator: operation.Text()}, f.File, operation.Position)

View File

@ -17,7 +17,6 @@ import (
type Function struct {
Name string
File *fs.File
Head token.List
Body token.List
Variables map[string]*Variable
Assembler asm.Assembler
@ -152,7 +151,10 @@ func (f *Function) TokenToRegister(t token.Token, register cpu.Register) error {
return errors.New(&errors.UnknownIdentifier{Name: name}, f.File, t.Position)
}
f.Assembler.RegisterRegister(asm.MOVE, register, variable.Register)
if register != variable.Register {
f.Assembler.RegisterRegister(asm.MOVE, register, variable.Register)
}
return nil
case token.Number:

View File

@ -8,9 +8,14 @@ import (
func (f *Function) CompileFunctionCall(expr *expression.Expression) error {
funcName := expr.Children[0].Token.Text()
parameters := expr.Children[1:]
registers := f.CPU.Syscall
if funcName != "syscall" {
registers = registers[1:]
}
for i := len(parameters) - 1; i >= 0; i-- {
err := f.ExpressionToRegister(parameters[i], f.CPU.Syscall[i])
err := f.ExpressionToRegister(parameters[i], registers[i])
if err != nil {
return err

View File

@ -5,9 +5,20 @@ import (
)
// List generates a list of expressions from comma separated parameters.
func List(tokens []token.Token) []*Expression {
func List(tokens token.List) []*Expression {
var list []*Expression
EachParameter(tokens, func(parameter token.List) error {
expression := Parse(parameter)
list = append(list, expression)
return nil
})
return list
}
// EachParameter calls the callback function on each parameter in a comma separated list.
func EachParameter(tokens token.List, call func(token.List) error) error {
start := 0
groupLevel := 0
@ -25,17 +36,20 @@ func List(tokens []token.Token) []*Expression {
}
parameter := tokens[start:i]
expression := Parse(parameter)
list = append(list, expression)
err := call(parameter)
if err != nil {
return err
}
start = i + 1
}
}
if start != len(tokens) {
parameter := tokens[start:]
expression := Parse(parameter)
list = append(list, expression)
return call(parameter)
}
return list
return nil
}

View File

@ -9,6 +9,7 @@ import (
"git.akyoto.dev/cli/q/src/build/arch/x64"
"git.akyoto.dev/cli/q/src/build/asm"
"git.akyoto.dev/cli/q/src/build/cpu"
"git.akyoto.dev/cli/q/src/build/expression"
"git.akyoto.dev/cli/q/src/build/fs"
"git.akyoto.dev/cli/q/src/build/token"
"git.akyoto.dev/cli/q/src/errors"
@ -100,6 +101,7 @@ func scanFile(path string, functions chan<- *Function) error {
blockLevel = 0
nameStart = -1
paramsStart = -1
paramsEnd = -1
bodyStart = -1
)
@ -128,12 +130,12 @@ func scanFile(path string, functions chan<- *Function) error {
for i < len(tokens) {
if tokens[i].Kind == token.GroupStart {
groupLevel++
i++
if groupLevel == 1 {
paramsStart = i
}
i++
continue
}
@ -144,12 +146,13 @@ func scanFile(path string, functions chan<- *Function) error {
return errors.New(errors.MissingGroupStart, file, tokens[i].Position)
}
i++
if groupLevel == 0 {
paramsEnd = i
i++
break
}
i++
continue
}
@ -221,17 +224,37 @@ func scanFile(path string, functions chan<- *Function) error {
return errors.New(errors.ExpectedFunctionDefinition, file, tokens[i].Position)
}
cpu := cpu.CPU{
General: x64.GeneralRegisters,
Syscall: x64.SyscallRegisters,
Return: x64.ReturnValueRegisters,
}
parameters := tokens[paramsStart:paramsEnd]
variables := map[string]*Variable{}
err := expression.EachParameter(parameters, func(parameter token.List) error {
if len(parameter) == 1 {
name := parameter[0].Text()
register := x64.SyscallRegisters[1+len(variables)]
variables[name] = &Variable{Name: name, Register: register}
cpu.Use(register)
return nil
}
return errors.New(errors.NotImplemented, file, parameter[0].Position)
})
if err != nil {
return err
}
functions <- &Function{
Name: tokens[nameStart].Text(),
File: file,
Head: tokens[paramsStart:bodyStart],
Body: tokens[bodyStart:i],
Variables: map[string]*Variable{},
CPU: cpu.CPU{
General: x64.GeneralRegisters,
Syscall: x64.SyscallRegisters,
Return: x64.ReturnValueRegisters,
},
Variables: variables,
CPU: cpu,
Assembler: asm.Assembler{
Instructions: make([]asm.Instruction, 0, 32),
},