~madcapjake/rhi

5ef217a8cb3dbb9e10030691e4ab422cd5eb54c9 — Jake Russo 1 year, 6 months ago 072132c
Update "func" to "rout" and add lit find algo
M internal/generator/visitor.go => internal/generator/visitor.go +44 -26
@@ 59,7 59,7 @@ func (v *RhumbVisitor) GetVM() *vm.VirtualMachine {
}

func (v *RhumbVisitor) Visit(tree antlr.ParseTree) interface{} {
	viLogger.Printf("input type: %s\n", reflect.TypeOf(tree))
	viLogger.Printf("Visit[tree type: %s]\n", reflect.TypeOf(tree))

	switch t := tree.(type) {
	case *antlr.ErrorNodeImpl:


@@ 74,7 74,7 @@ func (v *RhumbVisitor) Visit(tree antlr.ParseTree) interface{} {

func (v *RhumbVisitor) VisitChildren(node antlr.RuleNode) interface{} {
	for _, n := range node.GetChildren() {
		viLogger.Println("Visit child:", reflect.TypeOf(n))
		viLogger.Printf("VisitChildren[node type: %s]\n", reflect.TypeOf(n))
		v.Visit(n.(antlr.ParseTree))
	}
	return nil


@@ 98,13 98,21 @@ func (v *RhumbVisitor) VisitMutableLabel(ctx *P.MutableLabelContext) interface{}

func (v *RhumbVisitor) VisitLabelLiteral(ctx *P.LabelLiteralContext) interface{} {
	var (
		text string       = ctx.GetText()
		ra   vm.RuneArray = vm.NewRuneArray(&v.vm, word.FromAddress(0), []rune(text)...)
		text       string       = ctx.GetText()
		lits       vm.WordArray = v.vm.Routine.ReviveLits(&v.vm)
		lblIdx     uint64
		lblFindErr error
		ra         vm.RuneArray
	)
	viLogger.Println("label:", text)
	v.vm.WriteCodeToMain(
	lblIdx, lblFindErr = lits.Find(&v.vm, text)
	if lblFindErr != nil {
		ra = vm.NewRuneArray(&v.vm, word.FromAddress(0), []rune(text)...)
		lblIdx = ra.Id()
	}
	v.vm.WriteCodeToCurrentRoutine(
		ctx.GetStart().GetLine(),
		word.FromAddress(ra.Id()),
		word.FromAddress(lblIdx),
		vm.NewLocalRequest,
	)
	return v.VisitChildren(ctx)


@@ 114,20 122,26 @@ func (v *RhumbVisitor) VisitAssignment(ctx *P.AssignmentContext) interface{} {
	viLogger.Println("assignment!")
	// TODO: implement map assignment
	var (
		text string
		ra   vm.RuneArray
		text                  string
		ra                    vm.RuneArray
		lblIdx, opIdx         uint64
		lblFindErr, opFindErr error
		lits                  vm.WordArray = v.vm.Routine.ReviveLits(&v.vm)
	)
	if addr := ctx.GetAddress(); addr != nil {
		text = addr.GetText()
		viLogger.Println("Address:", text)
		// TODO: check for a matching subroutine and invoke
		// TODO: check for matching outer scoped label
		lblIdx, lblFindErr = lits.Find(&v.vm, text)
		if lblFindErr != nil {
			ra = vm.NewRuneArray(&v.vm, word.FromAddress(0), []rune(text)...)
			lblIdx = ra.Id()
		}

		ra = vm.NewRuneArray(&v.vm, word.FromAddress(0), []rune(text)...)

		v.vm.WriteCodeToMain(
		v.vm.WriteCodeToCurrentRoutine(
			addr.GetLine(),
			word.FromAddress(ra.Id()),
			word.FromAddress(lblIdx),
			vm.NewLocalRequest,
		)
	} else {


@@ 136,10 150,14 @@ func (v *RhumbVisitor) VisitAssignment(ctx *P.AssignmentContext) interface{} {
		viLogger.Printf("addrRef.Accept(v): %v\n", addrRef.Accept(v))
		text = addrRef.GetText()
		viLogger.Println("AddressRef:", text)
		ra = vm.NewRuneArray(&v.vm, word.FromAddress(0), []rune(text)...)
		v.vm.WriteCodeToMain(
		lblIdx, lblFindErr = lits.Find(&v.vm, text)
		if lblFindErr != nil {
			ra = vm.NewRuneArray(&v.vm, word.FromAddress(0), []rune(text)...)
			lblIdx = ra.Id()
		}
		v.vm.WriteCodeToCurrentRoutine(
			addrRef.GetStart().GetLine(),
			word.FromAddress(ra.Id()),
			word.FromAddress(lblIdx),
			vm.NewLocalRequest,
		)
	}


@@ 148,14 166,14 @@ func (v *RhumbVisitor) VisitAssignment(ctx *P.AssignmentContext) interface{} {
	viLogger.Println("ctx.Expression().Accept:", ctx.Expression().Accept(v))
	viLogger.Println("INNER:")
	op := ctx.AssignmentOp()
	ra = vm.NewRuneArray(
		&v.vm,
		word.FromAddress(0),
		[]rune(op.GetText())...,
	)
	v.vm.WriteCodeToMain(
	opIdx, opFindErr = lits.Find(&v.vm, op.GetText())
	if opFindErr != nil {
		ra = vm.NewRuneArray(&v.vm, word.FromAddress(0), []rune(op.GetText())...)
		opIdx = ra.Id()
	}
	v.vm.WriteCodeToCurrentRoutine(
		op.GetStart().GetLine(),
		word.FromAddress(ra.Id()),
		word.FromAddress(opIdx),
		vm.NewOuterRequest,
	)
	return nil


@@ 174,7 192,7 @@ func (v *RhumbVisitor) VisitIntegerLiteral(ctx *P.IntegerLiteralContext) interfa
		return RhumbReturn{nil, fmt.Errorf("unable to parse int")}
	}
	viLogger.Println("VALUE:", val)
	v.vm.WriteCodeToMain(
	v.vm.WriteCodeToCurrentRoutine(
		ctx.GetStart().GetLine(),
		word.FromInt(uint32(val)),
		vm.NewValueLiteral,


@@ 238,7 256,7 @@ func (v *RhumbVisitor) VisitMultiplicative(ctx *P.MultiplicativeContext) interfa
		exprs[i].Accept(v)
	}

	v.vm.WriteCodeToMain(
	v.vm.WriteCodeToCurrentRoutine(
		mulOp.GetStart().GetLine(),
		word.FromAddress(ra.Id()),
		vm.NewOuterRequest, // FIXME: re-implement as NewInnerRequest


@@ 262,7 280,7 @@ func (v *RhumbVisitor) VisitAdditive(ctx *P.AdditiveContext) interface{} {
		exprs[i].Accept(v)
	}

	v.vm.WriteCodeToMain(
	v.vm.WriteCodeToCurrentRoutine(
		addOp.GetStart().GetLine(),
		word.FromAddress(ra.Id()),
		vm.NewOuterRequest, // FIXME: re-implement as NewInnerRequest


@@ 319,7 337,7 @@ func (v *RhumbVisitor) VisitPower(ctx *P.PowerContext) interface{} {
	for i := range exprs {
		exprs[i].Accept(v)
	}
	v.vm.WriteCodeToMain(
	v.vm.WriteCodeToCurrentRoutine(
		powOp.GetStart().GetLine(),
		word.FromAddress(ra.Id()),
		vm.NewOuterRequest, // FIXME: re-implement as NewInnerRequest

M internal/vm/legend.go => internal/vm/legend.go +11 -27
@@ 54,16 54,14 @@ const (
	base_lgd_offset uint64 = 1
	base_swp_offset uint64 = 2
	base_sze_offset uint64 = 3
	base_len_offset uint64 = 3
	base_req_offset uint64 = 4
	base_dep_offset uint64 = 5
	main_fld_offset uint64 = 6
	list_arr_offset uint64 = 6
	list_fld_offset uint64 = 7
	text_arr_offset uint64 = 6
	text_fld_offset uint64 = 7
	func_chu_offset uint64 = 6
	func_fld_offset uint64 = 7
	base_len_offset uint64 = 4
	base_req_offset uint64 = 5
	base_dep_offset uint64 = 6
	main_fld_offset uint64 = 7
	text_arr_offset uint64 = 8
	text_fld_offset uint64 = 9
	rout_chu_offset uint64 = 10
	rout_fld_offset uint64 = 11
)

func NewBaseMapLegend(


@@ 90,7 88,7 @@ func wordsFromDescriptors(
	d ...Descriptor,
) (buf []word.Word) {
	// buf = make([]word.Word, 0, len(d)*3)
	// for descIndex := range d {
	// for _, desc := range d {
	// 	buf = append(buf, d[descIndex]...)
	// }
	return


@@ 110,20 108,6 @@ func NewMainMapLegend(
	)
}

func NewListMapLegend(
	legAddr word.Word,
	descs ...Descriptor,
) ListMapLegend {
	descCount := uint32(len(descs))
	dWords := wordsFromDescriptors(descs...)
	return NewBaseMapLegend(
		word.Word(word.LIST_LGD),
		legAddr,
		descCount,
		dWords,
	)
}

func NewTextMapLegend(
	legAddr word.Word,
	descs ...Descriptor,


@@ 138,14 122,14 @@ func NewTextMapLegend(
	)
}

func NewFuncMapLegend(
func NewRoutMapLegend(
	legAddr word.Word,
	descs ...Descriptor,
) FuncMapLegend {
	descCount := uint32(len(descs))
	dWords := wordsFromDescriptors(descs...)
	return NewBaseMapLegend(
		word.Word(word.FUNC_LGD),
		word.Word(word.ROUT_LGD),
		legAddr,
		descCount,
		dWords,

M internal/vm/map.go => internal/vm/map.go +2 -2
@@ 29,8 29,8 @@ func NewTextMap(count uint32, legAddr word.Word) RhumbMap {
	return NewMap(word.Word(word.TEXT_MAP), legAddr)
}

func NewFuncMap(count uint32, legAddr word.Word) RhumbMap {
	return NewMap(word.Word(word.FUNC_MAP), legAddr)
func NewRoutMap(count uint32, legAddr word.Word) RhumbMap {
	return NewMap(word.Word(word.ROUT_MAP), legAddr)
}

func NewMetaMap(count uint32, legAddr word.Word) RhumbMap {

M internal/vm/vm.go => internal/vm/vm.go +14 -12
@@ 18,11 18,11 @@ func init() {
}

type VirtualMachine struct {
	heap  []word.Word
	free  []bool
	stack []word.Word
	scope []map[string]uint64
	main  Chunk
	heap    []word.Word
	free    []bool
	stack   []word.Word
	scope   []map[string]uint64
	Routine Chunk
}

var DEBUG_WIDTH int = 10


@@ 98,7 98,9 @@ func NewVirtualMachine() *VirtualMachine {
	vm.stack = make([]word.Word, 0)
	vm.scope = make([]map[string]uint64, 0)
	vm.scope = append(vm.scope, make(map[string]uint64))
	vm.main = NewChunk(vm)

	// TODO: convert to actual routine
	vm.Routine = NewChunk(vm)
	return vm
}



@@ 244,22 246,22 @@ func (vm VirtualMachine) allocInPlace(x, y int, ws ...word.Word) {
// 	}
// }

func (vm *VirtualMachine) WriteCodeToMain(
func (vm *VirtualMachine) WriteCodeToCurrentRoutine(
	line int,
	lit word.Word,
	codeFactory func(i uint64) []Code,
) {
	id, _ := vm.main.AddLiteral(vm, lit)
	id, _ := vm.Routine.AddLiteral(vm, lit)
	codes := codeFactory(id)
	vm.main.WriteCode(vm, line, codes)
	vm.Routine.WriteCode(vm, line, codes)
}

func (vm *VirtualMachine) Disassemble() {
	vm.main.Disassemble(vm)
	vm.Routine.Disassemble(vm)
}

func (vm *VirtualMachine) Execute(lastValueFlag bool) {
	vm.main.Execute(vm)
	vm.Routine.Execute(vm)
	if lastValueFlag {
		if len(vm.stack) == 0 {
			fmt.Println("()")


@@ 364,7 366,7 @@ func (vm *VirtualMachine) SubmitUnderRequest(label word.Word) {
// Used for traversing primitives and compilations
func (vm *VirtualMachine) SubmitOuterRequest(label word.Word) {
	// FIXME: locate text
	lits := vm.main.ReviveLits(vm)
	lits := vm.Routine.ReviveLits(vm)
	addr, err := lits.IndexOf(vm, label)
	if err != nil {
		panic("unable to find word for outer request")

M internal/vm/word_array.go => internal/vm/word_array.go +25 -2
@@ 64,6 64,29 @@ func ReviveWordArray(vm *VirtualMachine, addr word.Word) WordArray {
	return WordArray{i}
}

func (wa WordArray) Find(vm *VirtualMachine, s string) (
	idx uint64,
	err error,
) {
	for i := range make([]int, wa.Length(vm)) {
		waVal := wa.Get(vm, i)
		if waVal.IsAddress() {
			heapVal := vm.heap[waVal.AsAddr()]
			if heapVal.IsRuneArrayMark() {
				heapRA := ReviveRuneArray(vm, waVal.AsAddr())
				strVal := heapRA.String(vm)
				if strVal == s {
					heapIdx := wa.id + word_arr_offset + uint64(i)
					idx = vm.heap[heapIdx].AsAddr()
					return
				}
			}
		}
	}
	err = fmt.Errorf("unable to find '%s'", s)
	return
}

func (wa WordArray) IndexOf(vm *VirtualMachine, x word.Word) (
	idx int,
	err error,


@@ 71,14 94,14 @@ func (wa WordArray) IndexOf(vm *VirtualMachine, x word.Word) (
	if x.IsAddress() {
		mkX := vm.heap[x.AsAddr()]
		if mkX.IsRuneArrayMark() {
			rax := ReviveRuneArray(vm, x.AsAddr())
			raX := ReviveRuneArray(vm, x.AsAddr())
			for i := range make([]int, wa.Length(vm)) {
				y := wa.Get(vm, i)
				if y.IsAddress() {
					mkY := vm.heap[y.AsAddr()]
					if mkY.IsRuneArrayMark() {
						ray := ReviveRuneArray(vm, y.AsAddr())
						if rax.String(vm) == ray.String(vm) {
						if raX.String(vm) == ray.String(vm) {
							return i, nil
						}
					}

M internal/word/word.go => internal/word/word.go +4 -4
@@ 34,7 34,7 @@ const MARK_MAP uint64 = 0x7F_FE_40_00_00_00_00_00
const MAIN_MAP uint64 = 0x7F_FE_40_10_00_00_00_00
const LIST_MAP uint64 = 0x7F_FE_40_20_00_00_00_00
const TEXT_MAP uint64 = 0x7F_FE_40_30_00_00_00_00
const FUNC_MAP uint64 = 0x7F_FE_40_40_00_00_00_00
const ROUT_MAP uint64 = 0x7F_FE_40_40_00_00_00_00
const META_MAP uint64 = 0x7F_FE_40_F0_00_00_00_00

const MARK_ARR uint64 = 0x7F_FE_80_00_00_00_00_00


@@ 49,7 49,7 @@ const MARK_LGD uint64 = 0x7F_FE_C0_00_00_00_00_00
const MAIN_LGD uint64 = 0x7F_FE_C0_10_00_00_00_00
const LIST_LGD uint64 = 0x7F_FE_C0_20_00_00_00_00
const TEXT_LGD uint64 = 0x7F_FE_C0_30_00_00_00_00
const FUNC_LGD uint64 = 0x7F_FE_C0_40_00_00_00_00
const ROUT_LGD uint64 = 0x7F_FE_C0_40_00_00_00_00
const ARRA_LGD uint64 = 0x7F_FE_C0_50_00_00_00_00
const META_LGD uint64 = 0x7F_FE_C0_F0_00_00_00_00



@@ 147,7 147,7 @@ func (w Word) IsMapMark() bool     { return w.isMark(MARK_MAP) }
func (w Word) IsMainMapMark() bool { return w.isMark2(MAIN_MAP) }
func (w Word) IsListMapMark() bool { return w.isMark2(LIST_MAP) }
func (w Word) IsTextMapMark() bool { return w.isMark2(TEXT_MAP) }
func (w Word) IsFuncMapMark() bool { return w.isMark2(FUNC_MAP) }
func (w Word) IsFuncMapMark() bool { return w.isMark2(ROUT_MAP) }
func (w Word) IsMetaMapMark() bool { return w.isMark2(META_MAP) }

func (w Word) IsArrayMark() bool     { return w.isMark(MARK_ARR) }


@@ 160,7 160,7 @@ func (w Word) IsLegendMark() bool     { return w.isMark(MARK_LGD) }
func (w Word) IsMainLegendMark() bool { return w.isMark2(MAIN_LGD) }
func (w Word) IsListLegendMark() bool { return w.isMark2(LIST_LGD) }
func (w Word) IsTextLegendMark() bool { return w.isMark2(TEXT_LGD) }
func (w Word) IsFuncLegendMark() bool { return w.isMark2(FUNC_LGD) }
func (w Word) IsFuncLegendMark() bool { return w.isMark2(ROUT_LGD) }
func (w Word) IsArraLegendMark() bool { return w.isMark2(ARRA_LGD) }
func (w Word) IsMetaLegendMark() bool { return w.isMark2(META_LGD) }