Added define operator
This commit is contained in:
parent
65791ea5a1
commit
cf696a6f10
@ -1,7 +1,7 @@
|
|||||||
main() {
|
main() {
|
||||||
write := 1
|
write := 1
|
||||||
exit := 60
|
|
||||||
stdout := 1
|
stdout := 1
|
||||||
|
exit := 60
|
||||||
|
|
||||||
syscall(write, stdout, 4194305, 3)
|
syscall(write, stdout, 4194305, 3)
|
||||||
syscall(exit, 0)
|
syscall(exit, 0)
|
||||||
|
@ -33,7 +33,8 @@ func (f *Function) Compile() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if config.Verbose {
|
if config.Verbose {
|
||||||
fmt.Println("[line]", line)
|
ansi.Dim.Print("[ ] ")
|
||||||
|
fmt.Println(line)
|
||||||
}
|
}
|
||||||
|
|
||||||
err := f.compileInstruction(line)
|
err := f.compileInstruction(line)
|
||||||
@ -45,6 +46,19 @@ func (f *Function) Compile() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
f.Assembler.Return()
|
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.
|
// compileInstruction compiles a single instruction.
|
||||||
@ -57,12 +71,13 @@ func (f *Function) compileInstruction(line token.List) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case token.Identifier:
|
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()
|
name := line[0].Text()
|
||||||
value := line[2:]
|
value := line[2:]
|
||||||
|
|
||||||
if config.Verbose {
|
if config.Verbose {
|
||||||
fmt.Println("[variable]", name, value)
|
ansi.Dim.Printf("[var] ")
|
||||||
|
fmt.Println(name, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
f.Variables[name] = &Variable{
|
f.Variables[name] = &Variable{
|
||||||
|
@ -2,7 +2,6 @@ package asm
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"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/config"
|
"git.akyoto.dev/cli/q/src/build/config"
|
||||||
@ -29,12 +28,12 @@ func (a *Assembler) Finalize() ([]byte, []byte) {
|
|||||||
for _, x := range a.Instructions {
|
for _, x := range a.Instructions {
|
||||||
switch x.Mnemonic {
|
switch x.Mnemonic {
|
||||||
case MOVE:
|
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{
|
pointers = append(pointers, Pointer{
|
||||||
Position: Address(len(code) - 4),
|
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))
|
dataStart := config.BaseAddress + config.CodeOffset + Address(len(code))
|
||||||
|
|
||||||
for _, pointer := range pointers {
|
for _, pointer := range pointers {
|
||||||
|
@ -5,15 +5,5 @@ import "fmt"
|
|||||||
// Instruction represents a single instruction which can be converted to machine code.
|
// Instruction represents a single instruction which can be converted to machine code.
|
||||||
type Instruction struct {
|
type Instruction struct {
|
||||||
Mnemonic Mnemonic
|
Mnemonic Mnemonic
|
||||||
Data interface{}
|
Data fmt.Stringer
|
||||||
}
|
|
||||||
|
|
||||||
// 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()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ import "git.akyoto.dev/cli/q/src/build/cpu"
|
|||||||
func (a *Assembler) MoveRegisterNumber(reg cpu.Register, number uint64) {
|
func (a *Assembler) MoveRegisterNumber(reg cpu.Register, number uint64) {
|
||||||
a.Instructions = append(a.Instructions, Instruction{
|
a.Instructions = append(a.Instructions, Instruction{
|
||||||
Mnemonic: MOVE,
|
Mnemonic: MOVE,
|
||||||
Data: RegisterNumber{
|
Data: &RegisterNumber{
|
||||||
Register: reg,
|
Register: reg,
|
||||||
Number: number,
|
Number: number,
|
||||||
IsPointer: false,
|
IsPointer: false,
|
||||||
@ -18,7 +18,7 @@ func (a *Assembler) MoveRegisterNumber(reg cpu.Register, number uint64) {
|
|||||||
func (a *Assembler) MoveRegisterAddress(reg cpu.Register, address Address) {
|
func (a *Assembler) MoveRegisterAddress(reg cpu.Register, address Address) {
|
||||||
a.Instructions = append(a.Instructions, Instruction{
|
a.Instructions = append(a.Instructions, Instruction{
|
||||||
Mnemonic: MOVE,
|
Mnemonic: MOVE,
|
||||||
Data: RegisterNumber{
|
Data: &RegisterNumber{
|
||||||
Register: reg,
|
Register: reg,
|
||||||
Number: uint64(address),
|
Number: uint64(address),
|
||||||
IsPointer: true,
|
IsPointer: true,
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
package asm
|
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.
|
// RegisterNumber operates with a register and a number.
|
||||||
type RegisterNumber struct {
|
type RegisterNumber struct {
|
||||||
@ -8,3 +12,8 @@ type RegisterNumber struct {
|
|||||||
Number uint64
|
Number uint64
|
||||||
IsPointer bool
|
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 represents a series of numerical characters.
|
||||||
Number
|
Number
|
||||||
|
|
||||||
|
// Define represents the assignment operator `:=` for a new variable.
|
||||||
|
Define
|
||||||
|
|
||||||
// Operator represents a mathematical operator.
|
// Operator represents a mathematical operator.
|
||||||
Operator
|
Operator
|
||||||
|
|
||||||
@ -63,6 +66,7 @@ func (kind Kind) String() string {
|
|||||||
"Keyword",
|
"Keyword",
|
||||||
"String",
|
"String",
|
||||||
"Number",
|
"Number",
|
||||||
|
"Define",
|
||||||
"Operator",
|
"Operator",
|
||||||
"Separator",
|
"Separator",
|
||||||
"Comment",
|
"Comment",
|
||||||
|
@ -13,7 +13,7 @@ func (list List) String() string {
|
|||||||
var last Token
|
var last Token
|
||||||
|
|
||||||
for _, t := range list {
|
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(' ')
|
builder.WriteByte(' ')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package token
|
package token
|
||||||
|
|
||||||
|
import "bytes"
|
||||||
|
|
||||||
// Pre-allocate these byte buffers so we can re-use them
|
// Pre-allocate these byte buffers so we can re-use them
|
||||||
// instead of allocating a new buffer every time.
|
// instead of allocating a new buffer every time.
|
||||||
var (
|
var (
|
||||||
@ -10,6 +12,7 @@ var (
|
|||||||
arrayStartBytes = []byte{'['}
|
arrayStartBytes = []byte{'['}
|
||||||
arrayEndBytes = []byte{']'}
|
arrayEndBytes = []byte{']'}
|
||||||
separatorBytes = []byte{','}
|
separatorBytes = []byte{','}
|
||||||
|
defineBytes = []byte{':', '='}
|
||||||
newLineBytes = []byte{'\n'}
|
newLineBytes = []byte{'\n'}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -38,12 +41,7 @@ func Tokenize(buffer []byte) List {
|
|||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
|
|
||||||
tokens = append(tokens, Token{
|
tokens = append(tokens, Token{String, start, buffer[start:end]})
|
||||||
String,
|
|
||||||
start,
|
|
||||||
buffer[start:end],
|
|
||||||
})
|
|
||||||
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
// Parentheses start
|
// Parentheses start
|
||||||
@ -88,11 +86,7 @@ func Tokenize(buffer []byte) List {
|
|||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
|
|
||||||
token := Token{
|
token := Token{Identifier, position, buffer[position:i]}
|
||||||
Identifier,
|
|
||||||
position,
|
|
||||||
buffer[position:i],
|
|
||||||
}
|
|
||||||
|
|
||||||
if Keywords[string(token.Bytes)] {
|
if Keywords[string(token.Bytes)] {
|
||||||
token.Kind = Keyword
|
token.Kind = Keyword
|
||||||
@ -111,12 +105,7 @@ func Tokenize(buffer []byte) List {
|
|||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
|
|
||||||
tokens = append(tokens, Token{
|
tokens = append(tokens, Token{Number, position, buffer[position:i]})
|
||||||
Number,
|
|
||||||
position,
|
|
||||||
buffer[position:i],
|
|
||||||
})
|
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,12 +118,12 @@ func Tokenize(buffer []byte) List {
|
|||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
|
|
||||||
tokens = append(tokens, Token{
|
if bytes.Equal(buffer[position:i], defineBytes) {
|
||||||
Operator,
|
tokens = append(tokens, Token{Define, position, defineBytes})
|
||||||
position,
|
continue
|
||||||
buffer[position:i],
|
}
|
||||||
})
|
|
||||||
|
|
||||||
|
tokens = append(tokens, Token{Operator, position, buffer[position:i]})
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user