M .vscode/launch.json => .vscode/launch.json +8 -3
@@ 19,15 19,20 @@
"program": "cmd/rhumb/main.go",
"args": [
"line",
- "--disassemble",
+ // "--disassemble",
+ "--last-value",
+
+ // "foo := 1; bar .= 2; foo ++ bar",
+
+
"foo .= 10",
"bar .= 3",
"foo ** bar // 6"
],
"env": {
"RHUMB_VISITOR_DEBUG": "0",
- "RHUMB_CODE_ARRAY_DEBUG": "1",
- "RHUMB_VM_DEBUG": "1"
+ "RHUMB_CODE_ARRAY_DEBUG": "0",
+ "RHUMB_VM_DEBUG": "0"
}
}
M internal/cli/cli.go => internal/cli/cli.go +14 -5
@@ 17,14 17,18 @@ import (
type visitorContextKey int
type disassembleContextKey int
+type lastValueContextKey int
const VisitorCK visitorContextKey = iota
const DisassembleCK disassembleContextKey = iota
+const LastValueCK lastValueContextKey = iota
-func disassembleFlag(ctx *context.Context, args *[]string) ([]string, error) {
+func setupFlags(ctx *context.Context, args *[]string) ([]string, error) {
flags := flag.NewFlagSet("rhumb", flag.ContinueOnError)
var disassemble bool
flags.BoolVar(&disassemble, "disassemble", false, "Disassemble the chunk of code")
+ var lastValue bool
+ flags.BoolVar(&lastValue, "last-value", false, "Print the last value of the main routine")
if err := flags.Parse(*args); err != nil {
return []string{}, err
}
@@ 34,6 38,11 @@ func disassembleFlag(ctx *context.Context, args *[]string) ([]string, error) {
} else {
*ctx = context.WithValue(*ctx, DisassembleCK, false)
}
+ if lastValue {
+ *ctx = context.WithValue(*ctx, LastValueCK, true)
+ } else {
+ *ctx = context.WithValue(*ctx, LastValueCK, false)
+ }
return flags.Args(), nil
}
@@ 53,12 62,12 @@ func parse(ctx context.Context, chars antlr.CharStream) {
if ctx.Value(DisassembleCK).(bool) {
vm.Disassemble()
}
- vm.Execute()
+ vm.Execute(ctx.Value(LastValueCK).(bool))
}
func ParseFile(ctx context.Context, args []string) error {
var err error
- if args, err = disassembleFlag(&ctx, &args); err != nil {
+ if args, err = setupFlags(&ctx, &args); err != nil {
return err
}
input, err := antlr.NewFileStream(args[1])
@@ 72,7 81,7 @@ func ParseFile(ctx context.Context, args []string) error {
func ParseLines(ctx context.Context, args []string) error {
var err error
- if args, err = disassembleFlag(&ctx, &args); err != nil {
+ if args, err = setupFlags(&ctx, &args); err != nil {
return err
}
input := antlr.NewInputStream(strings.Join(args, "\n"))
@@ 82,7 91,7 @@ func ParseLines(ctx context.Context, args []string) error {
func ReadEvalPrintLoop(ctx context.Context, args []string) error {
var err error
- if args, err = disassembleFlag(&ctx, &args); err != nil {
+ if args, err = setupFlags(&ctx, &args); err != nil {
return err
}
for {
M internal/generator/visitor.go => internal/generator/visitor.go +1 -1
@@ 19,7 19,7 @@ var viLogger = log.New(io.Discard, "", log.LstdFlags)
func init() {
if os.Getenv("RHUMB_VISITOR_DEBUG") == "1" {
- viLogger = log.New(os.Stdout, "{VI} ", log.LstdFlags)
+ viLogger = log.New(os.Stdout, "{VI} ", log.Ltime)
}
}
M internal/vm/code_array.go => internal/vm/code_array.go +7 -10
@@ 125,7 125,6 @@ func (ca *CodeArray) SetCodes(
byteSz uint32 = 8
codeID int
code Code
- initSz uint32
bs []byte = make([]byte, 0, byteSz)
ws []word.Word = make([]word.Word, 0, newLen/8)
lastWordID uint64 = ca.id + uint64(ca.Size(vm)) - 1
@@ 133,24 132,24 @@ func (ca *CodeArray) SetCodes(
if newLine {
ws = append(ws, word.Sentinel())
} else {
- if ca.lastWordVacancy(vm) {
- ca.getCodesFromWord(vm, vm.heap[lastWordID], &bs)
+ ca.getCodesFromWord(vm, vm.heap[lastWordID], &bs)
+ if len(bs) < 8 {
vm.free[lastWordID] = true
origSz--
- initSz = uint32(len(bs))
tempCS := make([]Code, len(cs))
copy(tempCS, cs)
for codeID, code = range tempCS {
bs = append(bs, byte(code))
cs = cs[codeID+1:] // shift from main cs var
- if initSz+uint32(codeID)+1 == byteSz {
+ if len(bs) == int(byteSz) {
ws = append(ws,
word.Word(binary.BigEndian.Uint64(bs)))
bs = make([]byte, 0, byteSz)
break
}
}
-
+ } else {
+ bs = make([]byte, 0, byteSz)
}
}
for codeID, code = range cs {
@@ 169,10 168,8 @@ func (ca *CodeArray) SetCodes(
bsWord := word.Word(binary.BigEndian.Uint64(bs))
ws = append(ws, bsWord)
}
- wordsLen := uint32(len(ws))
- finalLength := uint32(origLen) + newLen
- ca.SetSize(vm, origSz+wordsLen)
- ca.SetLength(vm, finalLength)
+ ca.SetSize(vm, origSz+uint32(len(ws)))
+ ca.SetLength(vm, uint32(origLen)+newLen)
newId, _ := vm.Allocate(
int(ca.id),
int(origSz),
M internal/vm/vm.go => internal/vm/vm.go +53 -43
@@ 13,7 13,7 @@ var vmLogger = log.New(io.Discard, "", log.LstdFlags)
func init() {
if os.Getenv("RHUMB_VM_DEBUG") == "1" {
- vmLogger = log.New(os.Stdout, "{VM} ", log.LstdFlags)
+ vmLogger = log.New(os.Stdout, "{VM} ", log.Ltime)
}
}
@@ 37,53 37,56 @@ func incCheckNL(inc *int) {
}
func (vm VirtualMachine) DebugHeap() {
- for i := 0; i < len(vm.heap); i++ {
- if i%DEBUG_WIDTH == 0 {
- fmt.Println()
- }
- if vm.free[i] {
- fmt.Printf("{%3v: }", i)
- } else if vm.heap[i].IsRuneArrayMark() {
- j := i
- fmt.Printf("[%3v: %-9s ]", j, vm.heap[j].Debug())
- incCheckNL(&j)
- fmt.Printf("[%3v: %-9s ]", j, vm.heap[j].Debug())
- incCheckNL(&j)
- fmt.Printf("[%3v: %-9s ]", j, vm.heap[j].Debug())
- incCheckNL(&j)
- fmt.Printf("[%3v: %-9s ]", j, vm.heap[j].Debug())
- incCheckNL(&j)
- fmt.Printf("[%3v: ", j)
- ra := ReviveRuneArray(&vm, uint64(i))
- runes := ra.Runes(&vm)
- if len(runes) <= 2 {
- for _, r := range runes {
- fmt.Printf("'%s'", string(r))
- fmt.Print(" ")
- }
- } else {
- for i, r := range runes {
- fmt.Printf("'%s'", string(r))
- if i%2 == 1 {
- fmt.Print(" |")
- incCheckNL(&j)
- fmt.Print("| ")
- } else {
+ if os.Getenv("RHUMB_VM_DEBUG") == "1" {
+ vmLogger.Println("Dumping memory...")
+ for i := 0; i < len(vm.heap); i++ {
+ if i > 0 && i%DEBUG_WIDTH == 0 {
+ fmt.Println()
+ }
+ if vm.free[i] {
+ fmt.Printf("{%3v: }", i)
+ } else if vm.heap[i].IsRuneArrayMark() {
+ j := i
+ fmt.Printf("[%3v: %-9s ]", j, vm.heap[j].Debug())
+ incCheckNL(&j)
+ fmt.Printf("[%3v: %-9s ]", j, vm.heap[j].Debug())
+ incCheckNL(&j)
+ fmt.Printf("[%3v: %-9s ]", j, vm.heap[j].Debug())
+ incCheckNL(&j)
+ fmt.Printf("[%3v: %-9s ]", j, vm.heap[j].Debug())
+ incCheckNL(&j)
+ fmt.Printf("[%3v: ", j)
+ ra := ReviveRuneArray(&vm, uint64(i))
+ runes := ra.Runes(&vm)
+ if len(runes) <= 2 {
+ for _, r := range runes {
+ fmt.Printf("'%s'", string(r))
fmt.Print(" ")
}
- }
- for range make([]int, (ra.Length(&vm) % 2)) {
- fmt.Print(" ")
- }
+ } else {
+ for i, r := range runes {
+ fmt.Printf("'%s'", string(r))
+ if i%2 == 1 {
+ fmt.Print(" |")
+ incCheckNL(&j)
+ fmt.Print("| ")
+ } else {
+ fmt.Print(" ")
+ }
+ }
+ for range make([]int, (ra.Length(&vm) % 2)) {
+ fmt.Print(" ")
+ }
+ }
+ fmt.Print("]")
+ i += int(ra.Size(&vm)) - 1
+ } else {
+ fmt.Printf("[%3v: %-9s ]", i, vm.heap[i].Debug())
}
- fmt.Print("]")
- i += int(ra.Size(&vm)) - 1
- } else {
- fmt.Printf("[%3v: %-9s ]", i, vm.heap[i].Debug())
}
+ fmt.Println()
}
- fmt.Println()
}
func NewVirtualMachine() *VirtualMachine {
@@ 255,8 258,15 @@ func (vm *VirtualMachine) Disassemble() {
vm.main.Disassemble(vm)
}
-func (vm *VirtualMachine) Execute() {
+func (vm *VirtualMachine) Execute(lastValueFlag bool) {
vm.main.Execute(vm)
+ if lastValueFlag {
+ if len(vm.stack) == 0 {
+ fmt.Println("()")
+ } else {
+ fmt.Println(vm.stack[len(vm.stack)-1].AsInt())
+ }
+ }
}
func logAddedToStack(stack []word.Word, txt string) {