Added define operator
This commit is contained in:
parent
65791ea5a1
commit
cf696a6f10
@ -1,7 +1,7 @@
|
||||
main() {
|
||||
write := 1
|
||||
exit := 60
|
||||
stdout := 1
|
||||
exit := 60
|
||||
|
||||
syscall(write, stdout, 4194305, 3)
|
||||
syscall(exit, 0)
|
||||
|
@ -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{
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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",
|
||||
|
@ -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(' ')
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user