Added call registers
This commit is contained in:
parent
735057ac74
commit
dc497ba4fb
@ -1,8 +1,4 @@
|
||||
main() {
|
||||
hello()
|
||||
}
|
||||
|
||||
hello() {
|
||||
address := 0
|
||||
length := 0
|
||||
|
||||
@ -15,6 +11,7 @@ hello() {
|
||||
length *= 10
|
||||
length /= 100
|
||||
length = (0 + 50 - 20) * 10 / 100
|
||||
length = 1
|
||||
|
||||
loop {
|
||||
print(address, length)
|
||||
@ -22,7 +19,7 @@ hello() {
|
||||
}
|
||||
|
||||
print(address, length) {
|
||||
write(1, address, length)
|
||||
write(length, address, length+1)
|
||||
}
|
||||
|
||||
write(fd, address, length) {
|
||||
|
@ -33,6 +33,32 @@ func (f *Function) Execute(operation token.Token, register cpu.Register, value *
|
||||
return f.ExecuteRegisterRegister(operation, register, temporary)
|
||||
}
|
||||
|
||||
// ExecuteFunctionCall executes a function call.
|
||||
func (f *Function) ExecuteFunctionCall(expr *expression.Expression) error {
|
||||
funcName := expr.Children[0].Token.Text()
|
||||
parameters := expr.Children[1:]
|
||||
|
||||
if funcName == "syscall" {
|
||||
err := f.ExpressionsToRegisters(parameters, f.CPU.Syscall)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f.Assembler.Syscall()
|
||||
} else {
|
||||
err := f.ExpressionsToRegisters(parameters, f.CPU.Call)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f.Assembler.Call(funcName)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ExecuteLeaf performs an operation on a register with the given leaf operand.
|
||||
func (f *Function) ExecuteLeaf(operation token.Token, register cpu.Register, operand token.Token) error {
|
||||
switch operand.Kind {
|
||||
|
@ -113,7 +113,7 @@ func (f *Function) CompileInstruction(line token.List) error {
|
||||
}
|
||||
|
||||
if isFunctionCall(expr) {
|
||||
return f.CompileFunctionCall(expr)
|
||||
return f.ExecuteFunctionCall(expr)
|
||||
}
|
||||
|
||||
return errors.New(&errors.InvalidInstruction{Instruction: expr.Token.Text()}, f.File, expr.Token.Position)
|
||||
@ -139,6 +139,19 @@ func (f *Function) ExpressionToRegister(root *expression.Expression, register cp
|
||||
return f.Execute(operation, register, right)
|
||||
}
|
||||
|
||||
// ExpressionsToRegisters moves multiple expressions into the specified registers.
|
||||
func (f *Function) ExpressionsToRegisters(expressions []*expression.Expression, registers []cpu.Register) error {
|
||||
for i := len(expressions) - 1; i >= 0; i-- {
|
||||
err := f.ExpressionToRegister(expressions[i], registers[i])
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// TokenToRegister moves a token into a register.
|
||||
// It only works with identifiers, numbers and strings.
|
||||
func (f *Function) TokenToRegister(t token.Token, register cpu.Register) error {
|
||||
|
@ -1,32 +0,0 @@
|
||||
package build
|
||||
|
||||
import (
|
||||
"git.akyoto.dev/cli/q/src/build/expression"
|
||||
)
|
||||
|
||||
// CompileFunctionCall compiles a top-level function call.
|
||||
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], registers[i])
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if funcName == "syscall" {
|
||||
f.Assembler.Syscall()
|
||||
} else {
|
||||
f.Assembler.Call(funcName)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
@ -29,12 +29,12 @@ func (f *Function) CompileVariableDefinition(expr *expression.Expression) error
|
||||
return err
|
||||
}
|
||||
|
||||
f.CPU.Use(reg)
|
||||
|
||||
f.Variables[name] = &Variable{
|
||||
variable := &Variable{
|
||||
Name: name,
|
||||
Register: reg,
|
||||
}
|
||||
|
||||
f.Variables[name] = variable
|
||||
f.CPU.Use(reg)
|
||||
return nil
|
||||
}
|
||||
|
@ -21,6 +21,9 @@ const (
|
||||
R15
|
||||
)
|
||||
|
||||
var GeneralRegisters = []cpu.Register{RBX, RBP, R12, R13, R14, R15}
|
||||
var SyscallRegisters = []cpu.Register{RAX, RDI, RSI, RDX, R10, R8, R9}
|
||||
var ReturnValueRegisters = []cpu.Register{RAX, RCX, R11}
|
||||
var (
|
||||
CallRegisters = []cpu.Register{RDI, RSI, RDX, RCX, R8, R9}
|
||||
GeneralRegisters = []cpu.Register{RBX, RBP, R12, R13, R14, R15}
|
||||
SyscallRegisters = []cpu.Register{RAX, RDI, RSI, RDX, R10, R8, R9}
|
||||
ReturnValueRegisters = []cpu.Register{RAX, RCX, R11}
|
||||
)
|
||||
|
@ -2,6 +2,7 @@ package cpu
|
||||
|
||||
// CPU represents the processor.
|
||||
type CPU struct {
|
||||
Call []Register
|
||||
General []Register
|
||||
Syscall []Register
|
||||
Return []Register
|
||||
|
@ -225,6 +225,7 @@ func scanFile(path string, functions chan<- *Function) error {
|
||||
}
|
||||
|
||||
cpu := cpu.CPU{
|
||||
Call: x64.CallRegisters,
|
||||
General: x64.GeneralRegisters,
|
||||
Syscall: x64.SyscallRegisters,
|
||||
Return: x64.ReturnValueRegisters,
|
||||
|
Loading…
Reference in New Issue
Block a user