From 8e64271f74316674c25f17f5783088f666277c95 Mon Sep 17 00:00:00 2001 From: Eduard Urbach Date: Thu, 27 Jun 2024 10:12:41 +0200 Subject: [PATCH] Implemented parameters --- examples/hello/hello.q | 17 ++++++++------ src/build/Execute.go | 4 +++- src/build/Function.go | 6 +++-- src/build/FunctionCall.go | 7 +++++- src/build/expression/List.go | 26 +++++++++++++++++----- src/build/scan.go | 43 +++++++++++++++++++++++++++--------- 6 files changed, 76 insertions(+), 27 deletions(-) diff --git a/examples/hello/hello.q b/examples/hello/hello.q index 9032441..ef15401 100644 --- a/examples/hello/hello.q +++ b/examples/hello/hello.q @@ -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) } \ No newline at end of file diff --git a/src/build/Execute.go b/src/build/Execute.go index 1f78ae0..84e51d6 100644 --- a/src/build/Execute.go +++ b/src/build/Execute.go @@ -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) diff --git a/src/build/Function.go b/src/build/Function.go index 9d90c42..ba070c2 100644 --- a/src/build/Function.go +++ b/src/build/Function.go @@ -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: diff --git a/src/build/FunctionCall.go b/src/build/FunctionCall.go index 9c90ee7..8f2c2ea 100644 --- a/src/build/FunctionCall.go +++ b/src/build/FunctionCall.go @@ -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 diff --git a/src/build/expression/List.go b/src/build/expression/List.go index b6fe4a6..2bb4b56 100644 --- a/src/build/expression/List.go +++ b/src/build/expression/List.go @@ -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 } diff --git a/src/build/scan.go b/src/build/scan.go index fea378a..af81199 100644 --- a/src/build/scan.go +++ b/src/build/scan.go @@ -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), },