Added define operator

This commit is contained in:
Eduard Urbach 2024-06-15 11:36:57 +02:00
parent 65791ea5a1
commit cf696a6f10
Signed by: akyoto
GPG Key ID: C874F672B1AF20C0
9 changed files with 51 additions and 51 deletions

View File

@ -1,7 +1,7 @@
main() {
write := 1
exit := 60
stdout := 1
exit := 60
syscall(write, stdout, 4194305, 3)
syscall(exit, 0)

View File

@ -33,7 +33,8 @@ func (f *Function) Compile() {
}
if config.Verbose {
fmt.Println("[line]", line)
ansi.Dim.Print("[ ] ")
fmt.Println(line)
}
err := f.compileInstruction(line)
@ -45,6 +46,19 @@ func (f *Function) Compile() {
}
f.Assembler.Return()
if config.Verbose {
for _, x := range f.Assembler.Instructions {
ansi.Dim.Print("[asm] ")
fmt.Print(x.Mnemonic.String())
if x.Data != nil {
fmt.Print(" " + x.Data.String())
}
fmt.Print("\n")
}
}
}
// compileInstruction compiles a single instruction.
@ -57,12 +71,13 @@ func (f *Function) compileInstruction(line token.List) error {
}
case token.Identifier:
if len(line) >= 2 && line[1].Kind == token.Operator && line[1].Text() == ":=" {
if len(line) >= 2 && line[1].Kind == token.Define {
name := line[0].Text()
value := line[2:]
if config.Verbose {
fmt.Println("[variable]", name, value)
ansi.Dim.Printf("[var] ")
fmt.Println(name, value)
}
f.Variables[name] = &Variable{

View File

@ -2,7 +2,6 @@ package asm
import (
"encoding/binary"
"fmt"
"git.akyoto.dev/cli/q/src/build/arch/x64"
"git.akyoto.dev/cli/q/src/build/config"
@ -29,12 +28,12 @@ func (a *Assembler) Finalize() ([]byte, []byte) {
for _, x := range a.Instructions {
switch x.Mnemonic {
case MOVE:
code = x64.MoveRegNum32(code, uint8(x.Data.(RegisterNumber).Register), uint32(x.Data.(RegisterNumber).Number))
code = x64.MoveRegNum32(code, uint8(x.Data.(*RegisterNumber).Register), uint32(x.Data.(*RegisterNumber).Number))
if x.Data.(RegisterNumber).IsPointer {
if x.Data.(*RegisterNumber).IsPointer {
pointers = append(pointers, Pointer{
Position: Address(len(code) - 4),
Address: Address(x.Data.(RegisterNumber).Number),
Address: Address(x.Data.(*RegisterNumber).Number),
})
}
@ -49,12 +48,6 @@ func (a *Assembler) Finalize() ([]byte, []byte) {
}
}
if config.Verbose {
for _, x := range a.Instructions {
fmt.Println("[asm]", x.String())
}
}
dataStart := config.BaseAddress + config.CodeOffset + Address(len(code))
for _, pointer := range pointers {

View File

@ -5,15 +5,5 @@ import "fmt"
// Instruction represents a single instruction which can be converted to machine code.
type Instruction struct {
Mnemonic Mnemonic
Data interface{}
}
// String returns a human readable version.
func (x *Instruction) String() string {
switch data := x.Data.(type) {
case RegisterNumber:
return fmt.Sprintf("%s %s, %x", x.Mnemonic, data.Register, data.Number)
default:
return x.Mnemonic.String()
}
Data fmt.Stringer
}

View File

@ -6,7 +6,7 @@ import "git.akyoto.dev/cli/q/src/build/cpu"
func (a *Assembler) MoveRegisterNumber(reg cpu.Register, number uint64) {
a.Instructions = append(a.Instructions, Instruction{
Mnemonic: MOVE,
Data: RegisterNumber{
Data: &RegisterNumber{
Register: reg,
Number: number,
IsPointer: false,
@ -18,7 +18,7 @@ func (a *Assembler) MoveRegisterNumber(reg cpu.Register, number uint64) {
func (a *Assembler) MoveRegisterAddress(reg cpu.Register, address Address) {
a.Instructions = append(a.Instructions, Instruction{
Mnemonic: MOVE,
Data: RegisterNumber{
Data: &RegisterNumber{
Register: reg,
Number: uint64(address),
IsPointer: true,

View File

@ -1,6 +1,10 @@
package asm
import "git.akyoto.dev/cli/q/src/build/cpu"
import (
"fmt"
"git.akyoto.dev/cli/q/src/build/cpu"
)
// RegisterNumber operates with a register and a number.
type RegisterNumber struct {
@ -8,3 +12,8 @@ type RegisterNumber struct {
Number uint64
IsPointer bool
}
// String returns a human readable version.
func (data *RegisterNumber) String() string {
return fmt.Sprintf("%s, %x", data.Register, data.Number)
}

View File

@ -25,6 +25,9 @@ const (
// Number represents a series of numerical characters.
Number
// Define represents the assignment operator `:=` for a new variable.
Define
// Operator represents a mathematical operator.
Operator
@ -63,6 +66,7 @@ func (kind Kind) String() string {
"Keyword",
"String",
"Number",
"Define",
"Operator",
"Separator",
"Comment",

View File

@ -13,7 +13,7 @@ func (list List) String() string {
var last Token
for _, t := range list {
if last.Kind == Keyword || last.Kind == Separator || last.Kind == Operator || t.Kind == Operator {
if last.Kind == Keyword || last.Kind == Separator || last.Kind == Define || t.Kind == Define {
builder.WriteByte(' ')
}

View File

@ -1,5 +1,7 @@
package token
import "bytes"
// Pre-allocate these byte buffers so we can re-use them
// instead of allocating a new buffer every time.
var (
@ -10,6 +12,7 @@ var (
arrayStartBytes = []byte{'['}
arrayEndBytes = []byte{']'}
separatorBytes = []byte{','}
defineBytes = []byte{':', '='}
newLineBytes = []byte{'\n'}
)
@ -38,12 +41,7 @@ func Tokenize(buffer []byte) List {
i++
}
tokens = append(tokens, Token{
String,
start,
buffer[start:end],
})
tokens = append(tokens, Token{String, start, buffer[start:end]})
continue
// Parentheses start
@ -88,11 +86,7 @@ func Tokenize(buffer []byte) List {
i++
}
token := Token{
Identifier,
position,
buffer[position:i],
}
token := Token{Identifier, position, buffer[position:i]}
if Keywords[string(token.Bytes)] {
token.Kind = Keyword
@ -111,12 +105,7 @@ func Tokenize(buffer []byte) List {
i++
}
tokens = append(tokens, Token{
Number,
position,
buffer[position:i],
})
tokens = append(tokens, Token{Number, position, buffer[position:i]})
continue
}
@ -129,12 +118,12 @@ func Tokenize(buffer []byte) List {
i++
}
tokens = append(tokens, Token{
Operator,
position,
buffer[position:i],
})
if bytes.Equal(buffer[position:i], defineBytes) {
tokens = append(tokens, Token{Define, position, defineBytes})
continue
}
tokens = append(tokens, Token{Operator, position, buffer[position:i]})
continue
}
}