~madcapjake/rhi

b55e3d5b0dd318ae989894253ab90d6a09d9dced — Jake Russo 1 year, 6 months ago 2d5f97f main
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
M internal/generator/visitor.go => internal/generator/visitor.go +1 -1
@@ 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}

M internal/vm/array-code.go => internal/vm/array-code.go +11 -11
@@ 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)
}

M internal/vm/array-rune.go => internal/vm/array-rune.go +9 -9
@@ 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)
	)

M internal/vm/array-word.go => internal/vm/array-word.go +5 -5
@@ 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)
}


M internal/vm/legend-list.go => internal/vm/legend-list.go +1 -1
@@ 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),

M internal/vm/legend-meta.go => internal/vm/legend-meta.go +1 -1
@@ 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

M internal/vm/legend-routine.go => internal/vm/legend-routine.go +1 -1
@@ 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

M internal/vm/legend-selector.go => internal/vm/legend-selector.go +1 -1
@@ 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

M internal/vm/legend-text.go => internal/vm/legend-text.go +1 -1
@@ 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

M internal/vm/legend.go => internal/vm/legend.go +5 -5
@@ 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)
}


M internal/vm/map.go => internal/vm/map.go +5 -5
@@ 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)
}

M internal/vm/primitives.go => internal/vm/primitives.go +48 -25
@@ 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

M internal/word/word.go => internal/word/word.go +4 -4
@@ 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 }