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() { hello() {
write := 1
stdout := 1
address := 0 address := 0
length := 0 length := 0
address += 4194304 address += 4194304
address += 1 address += 1
length = 0 + 1 length = address - address
length -= length
length += write + stdout
length -= length
length += 50 length += 50
length -= 20 length -= 20
length *= 10 length *= 10
@ -22,6 +17,14 @@ hello() {
length = (0 + 50 - 20) * 10 / 100 length = (0 + 50 - 20) * 10 / 100
loop { 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) f.Assembler.RegisterRegister(asm.DIV, destination, source)
case "=": case "=":
if destination != source {
f.Assembler.RegisterRegister(asm.MOVE, destination, source) f.Assembler.RegisterRegister(asm.MOVE, destination, source)
}
default: default:
return errors.New(&errors.InvalidOperator{Operator: operation.Text()}, f.File, operation.Position) return errors.New(&errors.InvalidOperator{Operator: operation.Text()}, f.File, operation.Position)

View File

@ -17,7 +17,6 @@ import (
type Function struct { type Function struct {
Name string Name string
File *fs.File File *fs.File
Head token.List
Body token.List Body token.List
Variables map[string]*Variable Variables map[string]*Variable
Assembler asm.Assembler 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) return errors.New(&errors.UnknownIdentifier{Name: name}, f.File, t.Position)
} }
if register != variable.Register {
f.Assembler.RegisterRegister(asm.MOVE, register, variable.Register) f.Assembler.RegisterRegister(asm.MOVE, register, variable.Register)
}
return nil return nil
case token.Number: case token.Number:

View File

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

View File

@ -5,9 +5,20 @@ import (
) )
// List generates a list of expressions from comma separated parameters. // 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 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 start := 0
groupLevel := 0 groupLevel := 0
@ -25,17 +36,20 @@ func List(tokens []token.Token) []*Expression {
} }
parameter := tokens[start:i] parameter := tokens[start:i]
expression := Parse(parameter) err := call(parameter)
list = append(list, expression)
if err != nil {
return err
}
start = i + 1 start = i + 1
} }
} }
if start != len(tokens) { if start != len(tokens) {
parameter := tokens[start:] parameter := tokens[start:]
expression := Parse(parameter) return call(parameter)
list = append(list, expression)
} }
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/arch/x64"
"git.akyoto.dev/cli/q/src/build/asm" "git.akyoto.dev/cli/q/src/build/asm"
"git.akyoto.dev/cli/q/src/build/cpu" "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/fs"
"git.akyoto.dev/cli/q/src/build/token" "git.akyoto.dev/cli/q/src/build/token"
"git.akyoto.dev/cli/q/src/errors" "git.akyoto.dev/cli/q/src/errors"
@ -100,6 +101,7 @@ func scanFile(path string, functions chan<- *Function) error {
blockLevel = 0 blockLevel = 0
nameStart = -1 nameStart = -1
paramsStart = -1 paramsStart = -1
paramsEnd = -1
bodyStart = -1 bodyStart = -1
) )
@ -128,12 +130,12 @@ func scanFile(path string, functions chan<- *Function) error {
for i < len(tokens) { for i < len(tokens) {
if tokens[i].Kind == token.GroupStart { if tokens[i].Kind == token.GroupStart {
groupLevel++ groupLevel++
i++
if groupLevel == 1 { if groupLevel == 1 {
paramsStart = i paramsStart = i
} }
i++
continue continue
} }
@ -144,12 +146,13 @@ func scanFile(path string, functions chan<- *Function) error {
return errors.New(errors.MissingGroupStart, file, tokens[i].Position) return errors.New(errors.MissingGroupStart, file, tokens[i].Position)
} }
i++
if groupLevel == 0 { if groupLevel == 0 {
paramsEnd = i
i++
break break
} }
i++
continue continue
} }
@ -221,17 +224,37 @@ func scanFile(path string, functions chan<- *Function) error {
return errors.New(errors.ExpectedFunctionDefinition, file, tokens[i].Position) return errors.New(errors.ExpectedFunctionDefinition, file, tokens[i].Position)
} }
functions <- &Function{ cpu := cpu.CPU{
Name: tokens[nameStart].Text(),
File: file,
Head: tokens[paramsStart:bodyStart],
Body: tokens[bodyStart:i],
Variables: map[string]*Variable{},
CPU: cpu.CPU{
General: x64.GeneralRegisters, General: x64.GeneralRegisters,
Syscall: x64.SyscallRegisters, Syscall: x64.SyscallRegisters,
Return: x64.ReturnValueRegisters, 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,
Body: tokens[bodyStart:i],
Variables: variables,
CPU: cpu,
Assembler: asm.Assembler{ Assembler: asm.Assembler{
Instructions: make([]asm.Instruction, 0, 32), Instructions: make([]asm.Instruction, 0, 32),
}, },