From b55e3d5b0dd318ae989894253ab90d6a09d9dced Mon Sep 17 00:00:00 2001 From: Jake Russo Date: Tue, 11 Apr 2023 17:10:30 -0500 Subject: [PATCH] Convert integer to signed 32 bit I wanted to use a full unsigned 32 bit and store the sign in a 33rd bit maybe an excercise for another time --- internal/generator/visitor.go | 2 +- internal/vm/array-code.go | 22 +++++----- internal/vm/array-rune.go | 18 ++++----- internal/vm/array-word.go | 10 ++--- internal/vm/legend-list.go | 2 +- internal/vm/legend-meta.go | 2 +- internal/vm/legend-routine.go | 2 +- internal/vm/legend-selector.go | 2 +- internal/vm/legend-text.go | 2 +- internal/vm/legend.go | 10 ++--- internal/vm/map.go | 10 ++--- internal/vm/primitives.go | 73 ++++++++++++++++++++++------------ internal/word/word.go | 8 ++-- 13 files changed, 93 insertions(+), 70 deletions(-) diff --git a/internal/generator/visitor.go b/internal/generator/visitor.go index 617cba5..1a1696c 100644 --- a/internal/generator/visitor.go +++ b/internal/generator/visitor.go @@ -194,7 +194,7 @@ func (v *RhumbVisitor) VisitIntegerLiteral(ctx *P.IntegerLiteralContext) interfa viLogger.Println("VALUE:", val) v.vm.WriteCodeToCurrentChunk( ctx.GetStart().GetLine(), - word.FromInt(uint32(val)), + word.FromInt(int32(val)), vm.NewValueLiteral, ) return RhumbReturn{val, nil} diff --git a/internal/vm/array-code.go b/internal/vm/array-code.go index 8733109..28df695 100644 --- a/internal/vm/array-code.go +++ b/internal/vm/array-code.go @@ -42,8 +42,8 @@ func NewCodeArray( legAddr word.Word, words ...word.Word, ) CodeArray { - wordsLen := uint32(len(words)) - wordsSize := uint32(code_arr_offset) + wordsLen + wordsLen := int32(len(words)) + wordsSize := int32(code_arr_offset) + wordsLen caWords := make([]word.Word, 0, wordsSize) caWords = append(caWords, /* Mark: */ word.Word(word.CODE_ARR), @@ -120,9 +120,9 @@ func (ca *CodeArray) SetCodes( ) { var ( origLen uint64 = uint64(ca.Length(vm)) - origSz uint32 = uint32(ca.Size(vm)) - newLen uint32 = uint32(len(cs)) - byteSz uint32 = 8 + origSz int32 = int32(ca.Size(vm)) + newLen int32 = int32(len(cs)) + byteSz int32 = 8 codeID int code Code bs []byte = make([]byte, 0, byteSz) @@ -168,8 +168,8 @@ func (ca *CodeArray) SetCodes( bsWord := word.Word(binary.BigEndian.Uint64(bs)) ws = append(ws, bsWord) } - ca.SetSize(vm, origSz+uint32(len(ws))) - ca.SetLength(vm, uint32(origLen)+newLen) + ca.SetSize(vm, origSz+int32(len(ws))) + ca.SetLength(vm, int32(origLen)+newLen) newId, _ := vm.Allocate( int(ca.id), int(origSz), @@ -227,7 +227,7 @@ func (ca CodeArray) GetCodes(vm *VirtualMachine) []byte { func (ca *CodeArray) GetLine(vm *VirtualMachine, codeIndex int) (lines int) { codes, cwLen, cwSize := 0, ca.Length(vm), ca.Size(vm) - if uint32(codeIndex) > cwLen { + if int32(codeIndex) > cwLen { panic("index greater than length") } for i := uint64(0); i < cwSize && codes <= codeIndex; i++ { @@ -250,14 +250,14 @@ func (ca CodeArray) Legend(vm *VirtualMachine) uint64 { func (ca CodeArray) Size(vm *VirtualMachine) uint64 { return uint64(vm.Heap[ca.id+code_sze_offset].AsInt()) } -func (ca CodeArray) Length(vm *VirtualMachine) uint32 { +func (ca CodeArray) Length(vm *VirtualMachine) int32 { return vm.Heap[ca.id+code_len_offset].AsInt() } -func (ca *CodeArray) SetSize(vm *VirtualMachine, s uint32) { +func (ca *CodeArray) SetSize(vm *VirtualMachine, s int32) { vm.Heap[ca.id+code_sze_offset] = word.FromInt(s) } -func (ca *CodeArray) SetLength(vm *VirtualMachine, l uint32) { +func (ca *CodeArray) SetLength(vm *VirtualMachine, l int32) { vm.Heap[ca.id+code_len_offset] = word.FromInt(l) } diff --git a/internal/vm/array-rune.go b/internal/vm/array-rune.go index e328723..b6cd593 100644 --- a/internal/vm/array-rune.go +++ b/internal/vm/array-rune.go @@ -38,9 +38,9 @@ func NewRuneArray( runes ...rune, ) RuneArray { var ( - runesLen uint32 = uint32(len(runes)) - runesRem uint32 = uint32(runesLen % 2) - runesCap uint32 = uint32(code_arr_offset) + (runesLen / 2) + runesRem + runesLen int32 = int32(len(runes)) + runesRem int32 = int32(runesLen % 2) + runesCap int32 = int32(code_arr_offset) + (runesLen / 2) + runesRem raWords []word.Word = make([]word.Word, 0, runesCap) runeBytes []byte wordBytes []byte @@ -101,7 +101,7 @@ func (ra RuneArray) Legend(vm *VirtualMachine) uint64 { func (ra RuneArray) Size(vm *VirtualMachine) uint64 { return uint64(vm.Heap[ra.id+rune_sze_offset].AsInt()) } -func (ra RuneArray) Length(vm *VirtualMachine) uint32 { +func (ra RuneArray) Length(vm *VirtualMachine) int32 { return vm.Heap[ra.id+rune_len_offset].AsInt() } func (ra RuneArray) Runes(vm *VirtualMachine) []rune { @@ -124,7 +124,7 @@ func (ra RuneArray) String(vm *VirtualMachine) string { return string(ra.Runes(vm)) } -func (ra RuneArray) Rune(vm *VirtualMachine, i uint32) rune { +func (ra RuneArray) Rune(vm *VirtualMachine, i int32) rune { addr := i / 2 offset := i % 2 bytes := make([]byte, 8) @@ -136,19 +136,19 @@ func (ra RuneArray) Rune(vm *VirtualMachine, i uint32) rune { } } -func (ra RuneArray) SetSize(vm *VirtualMachine, s uint32) { +func (ra RuneArray) SetSize(vm *VirtualMachine, s int32) { vm.Heap[ra.id+rune_sze_offset] = word.FromInt(s) } -func (ra RuneArray) SetLength(vm *VirtualMachine, l uint32) { +func (ra RuneArray) SetLength(vm *VirtualMachine, l int32) { vm.Heap[ra.id+rune_len_offset] = word.FromInt(l) } -func (ra RuneArray) SetRune(vm *VirtualMachine, i uint32, r rune) { +func (ra RuneArray) SetRune(vm *VirtualMachine, i int32, r rune) { var ( addr uint64 = uint64(i) / 2 id uint64 = ra.id + addr - offset uint32 = i % 2 + offset int32 = i % 2 runeBytes []byte = make([]byte, 4) wordBytes []byte = make([]byte, 8) ) diff --git a/internal/vm/array-word.go b/internal/vm/array-word.go index 7a50898..07e6fb0 100644 --- a/internal/vm/array-word.go +++ b/internal/vm/array-word.go @@ -22,8 +22,8 @@ func NewWordArray( legAddr word.Word, words ...word.Word, ) WordArray { - wordsLen := uint32(len(words)) - wordsSize := uint32(code_arr_offset) + wordsLen + wordsLen := int32(len(words)) + wordsSize := int32(code_arr_offset) + wordsLen waWords := make([]word.Word, 0, wordsSize) waWords = append(waWords, /* Mark: */ word.Word(word.LIST_ARR), @@ -112,8 +112,8 @@ func (wa WordArray) IndexOf(vm *VirtualMachine, x word.Word) ( } func (wa *WordArray) Append(vm *VirtualMachine, newWords ...word.Word) (uint64, error) { - oldLen := uint32(wa.Length(vm)) - newLen := oldLen + uint32(len(newWords)) + oldLen := int32(wa.Length(vm)) + newLen := oldLen + int32(len(newWords)) id, err := vm.Allocate(int(wa.id), wa.Size(vm), newWords...) if err != nil { panic("word array append failed") @@ -138,7 +138,7 @@ func (wa WordArray) Legend(vm *VirtualMachine, i int) word.Word { return vm.Heap[i] } -func (wa WordArray) SetLength(vm *VirtualMachine, l uint32) { +func (wa WordArray) SetLength(vm *VirtualMachine, l int32) { vm.Heap[wa.id+word_len_offset] = word.FromInt(l) } diff --git a/internal/vm/legend-list.go b/internal/vm/legend-list.go index dbed39a..8fc42c9 100644 --- a/internal/vm/legend-list.go +++ b/internal/vm/legend-list.go @@ -6,7 +6,7 @@ import ( func NewListLegend(virtualMachine *VirtualMachine) Legend { words := make([]word.Word, 0, 8) - init_size := uint32(lgd_fld_offset) + init_size := int32(lgd_fld_offset) dataArray := NewWordArray(virtualMachine, word.FromAddress(0)) words = append(words, /* Mark: */ word.Word(word.LIST_LGD), diff --git a/internal/vm/legend-meta.go b/internal/vm/legend-meta.go index b439d1e..c2ef7ef 100644 --- a/internal/vm/legend-meta.go +++ b/internal/vm/legend-meta.go @@ -6,7 +6,7 @@ import ( func NewMetaLegend(virtualMachine *VirtualMachine) Legend { words := make([]word.Word, 0, 8) - init_size := uint32(lgd_fld_offset) + init_size := int32(lgd_fld_offset) words = append(words, /* Mark: */ word.Word(word.LIST_LGD), /* Legend: */ word.FromAddress(0), // TODO: Implement Meta Legend diff --git a/internal/vm/legend-routine.go b/internal/vm/legend-routine.go index 918e351..598c35d 100644 --- a/internal/vm/legend-routine.go +++ b/internal/vm/legend-routine.go @@ -6,7 +6,7 @@ import ( func NewRoutLegend(virtualMachine *VirtualMachine) Legend { words := make([]word.Word, 0, 8) - init_size := uint32(lgd_fld_offset) + init_size := int32(lgd_fld_offset) words = append(words, /* Mark: */ word.Word(word.LIST_LGD), /* Legend: */ word.FromAddress(0), // TODO: Implement Meta Legend diff --git a/internal/vm/legend-selector.go b/internal/vm/legend-selector.go index 9201e81..a4d3c9c 100644 --- a/internal/vm/legend-selector.go +++ b/internal/vm/legend-selector.go @@ -6,7 +6,7 @@ import ( func NewSeleLegend(virtualMachine *VirtualMachine) Legend { words := make([]word.Word, 0, 8) - init_size := uint32(lgd_fld_offset) + init_size := int32(lgd_fld_offset) words = append(words, /* Mark: */ word.Word(word.LIST_LGD), /* Legend: */ word.FromAddress(0), // TODO: Implement Meta Legend diff --git a/internal/vm/legend-text.go b/internal/vm/legend-text.go index 49cf14c..f2e3f4c 100644 --- a/internal/vm/legend-text.go +++ b/internal/vm/legend-text.go @@ -6,7 +6,7 @@ import ( func NewTextLegend(virtualMachine *VirtualMachine) Legend { words := make([]word.Word, 0, 8) - init_size := uint32(lgd_fld_offset) + init_size := int32(lgd_fld_offset) words = append(words, /* Mark: */ word.Word(word.TEXT_LGD), /* Legend: */ word.FromAddress(0), // TODO: Implement Meta Legend diff --git a/internal/vm/legend.go b/internal/vm/legend.go index f8a6668..3d8c463 100644 --- a/internal/vm/legend.go +++ b/internal/vm/legend.go @@ -60,7 +60,7 @@ func (l Legend) NewDescriptor( word.FromAddress(name.id), word.FromAddress(0), // TODO: Req link word.FromAddress(0), // TODO: Dep link - word.FromInt(uint32(offset)), + word.FromInt(int32(offset)), } loc, _ := vm.Allocate(int(l.Id), int(l.Size(vm)), descWords...) if loc != l.Id { @@ -92,19 +92,19 @@ func (l Legend) Get(vm *VirtualMachine, name RuneArray) ( return -1, fmt.Errorf("couldn't find word") } -func (l Legend) Length(vm *VirtualMachine) uint32 { +func (l Legend) Length(vm *VirtualMachine) int32 { return vm.Heap[l.Id+lgd_len_offset].AsInt() } -func (l Legend) SetLength(vm *VirtualMachine, i uint32) { +func (l Legend) SetLength(vm *VirtualMachine, i int32) { vm.Heap[l.Id+lgd_len_offset] = word.FromInt(i) } -func (l Legend) Size(vm *VirtualMachine) uint32 { +func (l Legend) Size(vm *VirtualMachine) int32 { return vm.Heap[l.Id+lgd_sze_offset].AsInt() } -func (l Legend) SetSize(vm *VirtualMachine, i uint32) { +func (l Legend) SetSize(vm *VirtualMachine, i int32) { vm.Heap[l.Id+lgd_sze_offset] = word.FromInt(i) } diff --git a/internal/vm/map.go b/internal/vm/map.go index c2e72fa..a7d034c 100644 --- a/internal/vm/map.go +++ b/internal/vm/map.go @@ -73,7 +73,7 @@ func (m Map) Locate(vm *VirtualMachine, i int) uint64 { func (m Map) At(vm *VirtualMachine, i int) word.Word { mLen := m.Length(vm) - if i < 0 || uint32(i) >= mLen { + if i < 0 || int32(i) >= mLen { panic("index out of bounds") } return vm.Heap[m.Locate(vm, i)] @@ -87,22 +87,22 @@ func (m Map) SetLegend(vm *VirtualMachine, l uint64) { vm.Heap[m.Id+map_lgd_offset] = word.FromAddress(l) } -func (m Map) Length(vm *VirtualMachine) uint32 { +func (m Map) Length(vm *VirtualMachine) int32 { legend := m.ReviveLegend(vm) return legend.Length(vm) } -func (m Map) SetLength(vm *VirtualMachine, i uint32) { +func (m Map) SetLength(vm *VirtualMachine, i int32) { legend := m.ReviveLegend(vm) legend.SetLength(vm, i) } -func (m Map) Size(vm *VirtualMachine) uint32 { +func (m Map) Size(vm *VirtualMachine) int32 { legend := m.ReviveLegend(vm) return legend.Size(vm) } -func (m Map) SetSize(vm *VirtualMachine, i uint32) { +func (m Map) SetSize(vm *VirtualMachine, i int32) { legend := m.ReviveLegend(vm) legend.SetSize(vm, i) } diff --git a/internal/vm/primitives.go b/internal/vm/primitives.go index 6a473de..5584efa 100644 --- a/internal/vm/primitives.go +++ b/internal/vm/primitives.go @@ -11,11 +11,11 @@ import ( * _-/_ */ -func expBySquaring(x, n uint32) uint32 { +func expBySquaring(x, n int32) int32 { if n == 0 { return 1 } - var y uint32 = 1 + var y int32 = 1 for n > 1 { if n%2 == 0 { x = x * x @@ -36,20 +36,23 @@ func (vm *VirtualMachine) popStack() (popped word.Word) { return } -func (vm *VirtualMachine) gatherTwoInts() (val1, val2 uint32) { +func (vm *VirtualMachine) gatherTwoIntegers() ( + val1, val2 int32, err error, +) { stackVal2 := vm.popStack() stackVal1 := vm.popStack() if stackVal1.IsAddress() { - val1 = vm.Heap[stackVal1.AsAddr()].AsInt() - } else if stackVal1.IsInteger() { - val1 = stackVal1.AsInt() + stackVal1 = vm.Heap[stackVal1.AsAddr()] } if stackVal2.IsAddress() { - val2 = vm.Heap[stackVal2.AsAddr()].AsInt() - } else if stackVal2.IsInteger() { - val2 = stackVal2.AsInt() + stackVal2 = vm.Heap[stackVal2.AsAddr()] + } + if !(stackVal1.IsInteger()) || !(stackVal2.IsInteger()) { + err = fmt.Errorf("values are not integers") + return + } else { + return stackVal1.AsInt(), stackVal2.AsInt(), nil } - return } func (vm *VirtualMachine) assignScopeLabel(mut bool) { @@ -68,33 +71,53 @@ func (vm *VirtualMachine) assignMapLabel(mut bool) { } func (vm *VirtualMachine) addTwoInts() { - val1, val2 := vm.gatherTwoInts() - vm.Stack = append(vm.Stack, word.FromInt(val1+val2)) - logAddedToStack(vm.Stack, fmt.Sprint(val1, " + ", val2)) + if val1, val2, err := vm.gatherTwoIntegers(); err != nil { + panic("Implement floats") + } else { + vm.Stack = append(vm.Stack, word.FromInt(val1+val2)) + logAddedToStack(vm.Stack, fmt.Sprint(val1, " + ", val2)) + } + } func (vm *VirtualMachine) subTwoInts() { - val1, val2 := vm.gatherTwoInts() - vm.Stack = append(vm.Stack, word.FromInt(val1-val2)) - logAddedToStack(vm.Stack, fmt.Sprint(val1, " - ", val2)) + if val1, val2, err := vm.gatherTwoIntegers(); err != nil { + panic("Implement floats") + } else { + vm.Stack = append(vm.Stack, word.FromInt(val1-val2)) + logAddedToStack(vm.Stack, fmt.Sprint(val1, " - ", val2)) + } + } func (vm *VirtualMachine) mulTwoInts() { - val1, val2 := vm.gatherTwoInts() - vm.Stack = append(vm.Stack, word.FromInt(val1*val2)) - logAddedToStack(vm.Stack, fmt.Sprint(val1, " x ", val2, " ")) + if val1, val2, err := vm.gatherTwoIntegers(); err != nil { + panic("Implement floats") + } else { + vm.Stack = append(vm.Stack, word.FromInt(val1*val2)) + logAddedToStack(vm.Stack, fmt.Sprint(val1, " x ", val2, " ")) + } + } func (vm *VirtualMachine) divTwoInts() { - val1, val2 := vm.gatherTwoInts() - vm.Stack = append(vm.Stack, word.FromInt(val1/val2)) - logAddedToStack(vm.Stack, fmt.Sprint(val1, " / ", val2)) + if val1, val2, err := vm.gatherTwoIntegers(); err != nil { + panic("Implement floats") + } else { + vm.Stack = append(vm.Stack, word.FromInt(val1/val2)) + logAddedToStack(vm.Stack, fmt.Sprint(val1, " / ", val2)) + } + } func (vm *VirtualMachine) expTwoInts() { - val1, val2 := vm.gatherTwoInts() - vm.Stack = append(vm.Stack, word.FromInt(expBySquaring(val1, val2))) - logAddedToStack(vm.Stack, fmt.Sprint(val1, " ^ ", val2)) + if val1, val2, err := vm.gatherTwoIntegers(); err != nil { + panic("Implement floats") + } else { + vm.Stack = append(vm.Stack, word.FromInt(expBySquaring(val1, val2))) + logAddedToStack(vm.Stack, fmt.Sprint(val1, " ^ ", val2)) + } + } // New scope and add a sentinel to the stack diff --git a/internal/word/word.go b/internal/word/word.go index 92c7ddb..dfccc33 100644 --- a/internal/word/word.go +++ b/internal/word/word.go @@ -86,9 +86,9 @@ func NewWord(a any) Word { case bool: return FromBool(a) case int: - return FromInt(uint32(a)) + return FromInt(int32(a)) case int64: - return FromInt(uint32(a)) + return FromInt(int32(a)) case rune: return FromRune(a) default: @@ -121,7 +121,7 @@ func FromBool(b bool) Word { return Word(VAL_FALS) } } -func FromInt(i uint32) Word { return Word(VAL_NUMB | uint64(i)) } +func FromInt(i int32) Word { return Word(VAL_NUMB | uint64(i)) } func FromRune(r rune) Word { return Word(VAL_RUNE | uint64(r)) } func FromSym(a int) Word { return Word(VAL_SYMB | uint64(a)) } func FromAddress(a uint64) Word { return Word(VAL_ADDR | a) } @@ -323,7 +323,7 @@ func (w Word) AsFloat() float64 { float := math.Float64frombits(bits) return float } -func (w Word) AsInt() uint32 { return uint32(uint64(w) & ^VAL_NUMB) } +func (w Word) AsInt() int32 { return int32(uint64(w) & ^VAL_NUMB) } func (w Word) AsRune() rune { return rune(uint64(w) & ^VAL_RUNE) } func (w Word) AsSym() uint64 { return uint64(w) & ^VAL_SYMB } func (w Word) AsAddr() uint64 { return uint64(w) & ^VAL_ADDR } -- 2.45.2