diff --git a/src/asm/Memory.go b/src/asm/Memory.go index a183de6..1076405 100644 --- a/src/asm/Memory.go +++ b/src/asm/Memory.go @@ -3,6 +3,7 @@ package asm import ( "fmt" "math" + "strconv" "strings" "git.akyoto.dev/cli/q/src/cpu" @@ -31,12 +32,12 @@ func (mem *Memory) Format(custom string) string { tmp.WriteString("+") } - tmp.WriteString(fmt.Sprint(mem.Offset)) + tmp.WriteString(strconv.Itoa(int(mem.Offset))) } tmp.WriteString("], ") tmp.WriteString(custom) tmp.WriteString(", ") - tmp.WriteString(fmt.Sprint(mem.Length)) + tmp.WriteString(strconv.Itoa(int(mem.Length))) return tmp.String() } diff --git a/src/asm/MemoryNumber.go b/src/asm/MemoryNumber.go index 651a20b..47c39d5 100644 --- a/src/asm/MemoryNumber.go +++ b/src/asm/MemoryNumber.go @@ -1,8 +1,6 @@ package asm -import ( - "fmt" -) +import "strconv" // MemoryNumber operates with a memory address and a number. type MemoryNumber struct { @@ -12,7 +10,7 @@ type MemoryNumber struct { // String returns a human readable version. func (data *MemoryNumber) String() string { - return data.Address.Format(fmt.Sprint(data.Number)) + return data.Address.Format(strconv.Itoa(data.Number)) } // MemoryNumber adds an instruction with a memory address and a number. diff --git a/src/asm/Number.go b/src/asm/Number.go index 768b232..3f0271c 100644 --- a/src/asm/Number.go +++ b/src/asm/Number.go @@ -1,7 +1,7 @@ package asm import ( - "fmt" + "strconv" ) // Number operates with just a number. @@ -11,7 +11,7 @@ type Number struct { // String returns a human readable version. func (data *Number) String() string { - return fmt.Sprintf("%d", data.Number) + return strconv.Itoa(data.Number) } // Number adds an instruction with a number. diff --git a/src/asmc/call.go b/src/asmc/call.go index 940c0da..cf84156 100644 --- a/src/asmc/call.go +++ b/src/asmc/call.go @@ -24,7 +24,7 @@ func (c *compiler) call(x asm.Instruction) { } distance := destination - (pointer.Position + Address(pointer.Size)) - return Address(distance) + return distance } c.codePointers = append(c.codePointers, pointer) diff --git a/src/asmc/jump.go b/src/asmc/jump.go index e6d8f65..f01f547 100644 --- a/src/asmc/jump.go +++ b/src/asmc/jump.go @@ -40,7 +40,7 @@ func (c *compiler) jump(x asm.Instruction) { } distance := destination - (pointer.Position + Address(pointer.Size)) - return Address(distance) + return distance } c.codePointers = append(c.codePointers, pointer) diff --git a/src/asmc/resolvePointers.go b/src/asmc/resolvePointers.go index 0dc879e..112a0d1 100644 --- a/src/asmc/resolvePointers.go +++ b/src/asmc/resolvePointers.go @@ -40,7 +40,7 @@ restart: case 0xEB: // JMP jump = []byte{0xE9} default: - panic(fmt.Errorf("failed to increase pointer size for instruction 0x%x", opCode)) + panic(fmt.Sprintf("failed to increase pointer size for instruction 0x%x", opCode)) } pointer.Position += Address(len(jump) - int(pointer.OpSize)) @@ -90,9 +90,10 @@ restart: for _, pointer := range c.dllPointers { destination := importsStart + pointer.Resolve() - delta := destination - Address(c.codeStart+pointer.Position+Address(pointer.Size)) + from := c.codeStart + pointer.Position + Address(pointer.Size) + offset := destination - from slice := c.code[pointer.Position : pointer.Position+4] - binary.LittleEndian.PutUint32(slice, uint32(delta)) + binary.LittleEndian.PutUint32(slice, uint32(offset)) } } } diff --git a/src/core/ArrayElementToRegister.go b/src/core/ArrayElementToRegister.go index c623035..66777b9 100644 --- a/src/core/ArrayElementToRegister.go +++ b/src/core/ArrayElementToRegister.go @@ -29,7 +29,8 @@ func (f *Function) ArrayElementToRegister(node *expression.Expression, register Length: byte(1), } - if index.Token.IsNumeric() { + switch { + case index.Token.IsNumeric(): offset, err := f.ToNumber(index.Token) if err != nil { @@ -38,7 +39,7 @@ func (f *Function) ArrayElementToRegister(node *expression.Expression, register memory.Offset = int8(offset) - } else if index.Token.Kind == token.Identifier { + case index.Token.Kind == token.Identifier: indexName := index.Token.Text(f.File.Bytes) indexVariable := f.VariableByName(indexName) @@ -53,7 +54,8 @@ func (f *Function) ArrayElementToRegister(node *expression.Expression, register } memory.OffsetRegister = indexVariable.Register - } else { + + default: typ, err := f.ExpressionToRegister(index, register) if err != nil { diff --git a/src/core/CompileDelete.go b/src/core/CompileDelete.go index 6eae244..4792fb0 100644 --- a/src/core/CompileDelete.go +++ b/src/core/CompileDelete.go @@ -21,7 +21,7 @@ func (f *Function) CompileDelete(root *expression.Expression) error { f.SaveRegister(f.CPU.Input[0]) f.SaveRegister(f.CPU.Input[1]) f.RegisterRegister(asm.MOVE, f.CPU.Input[0], variable.Register) - f.RegisterNumber(asm.MOVE, f.CPU.Input[1], int(variable.Type.(*types.Pointer).To.Size())) + f.RegisterNumber(asm.MOVE, f.CPU.Input[1], variable.Type.(*types.Pointer).To.Size()) f.CallSafe(f.Functions["mem.free"], f.CPU.Input[:2]) return nil } diff --git a/src/core/ToNumber.go b/src/core/ToNumber.go index da73904..1978939 100644 --- a/src/core/ToNumber.go +++ b/src/core/ToNumber.go @@ -13,30 +13,28 @@ import ( func (f *Function) ToNumber(t token.Token) (int, error) { switch t.Kind { case token.Number: - digits := t.Text(f.File.Bytes) + var ( + digits = t.Text(f.File.Bytes) + number int64 + err error + ) - if strings.HasPrefix(digits, "0x") { - number, err := strconv.ParseInt(digits[2:], 16, 64) - return int(number), err + switch { + case strings.HasPrefix(digits, "0x"): + number, err = strconv.ParseInt(digits[2:], 16, 64) + case strings.HasPrefix(digits, "0o"): + number, err = strconv.ParseInt(digits[2:], 8, 64) + case strings.HasPrefix(digits, "0b"): + number, err = strconv.ParseInt(digits[2:], 2, 64) + default: + number, err = strconv.ParseInt(digits, 10, 64) } - if strings.HasPrefix(digits, "0o") { - number, err := strconv.ParseInt(digits[2:], 8, 64) - return int(number), err - } - - if strings.HasPrefix(digits, "0b") { - number, err := strconv.ParseInt(digits[2:], 2, 64) - return int(number), err - } - - number, err := strconv.Atoi(digits) - if err != nil { - return 0, errors.New(err, f.File, t.Position) + return 0, errors.New(errors.InvalidNumber, f.File, t.Position) } - return number, nil + return int(number), nil case token.Rune: r := t.Bytes(f.File.Bytes) diff --git a/src/token/Tokenize_test.go b/src/token/Tokenize_test.go index ab256cb..3ed541a 100644 --- a/src/token/Tokenize_test.go +++ b/src/token/Tokenize_test.go @@ -388,6 +388,21 @@ func TestLeadingZero(t *testing.T) { } } +func TestRange(t *testing.T) { + tokens := token.Tokenize([]byte("a..b")) + + expected := []token.Kind{ + token.Identifier, + token.Range, + token.Identifier, + token.EOF, + } + + for i, kind := range expected { + assert.Equal(t, tokens[i].Kind, kind) + } +} + func TestSeparator(t *testing.T) { tokens := token.Tokenize([]byte("a,b,c")) diff --git a/src/types/Array.go b/src/types/Array.go index fd6add2..b6629f0 100644 --- a/src/types/Array.go +++ b/src/types/Array.go @@ -1,7 +1,5 @@ package types -var String = &Array{Of: Int8} - // Array is the address of an object. type Array struct { Of Type diff --git a/src/types/Common.go b/src/types/Common.go index a846b61..87d5889 100644 --- a/src/types/Common.go +++ b/src/types/Common.go @@ -10,6 +10,7 @@ var ( Int8 = &Base{name: "int8", size: 1} Float64 = &Base{name: "float64", size: 8} Float32 = &Base{name: "float32", size: 4} + String = &Array{Of: Int8} ) var (