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) }