]> git.mdlowis.com Git - proto/forth.git/commitdiff
fixed offset and link logic
authorMichael D. Lowis <mike@mdlowis.com>
Thu, 18 Jul 2024 03:30:08 +0000 (23:30 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Thu, 18 Jul 2024 03:30:08 +0000 (23:30 -0400)
asm.rb
asm.s

diff --git a/asm.rb b/asm.rb
index 06ac54ba8b613adb7c447fe484fcc8fa4110fdcc..f25bb2028c4babe4f4c7a29e892d8ea878e547b2 100755 (executable)
--- a/asm.rb
+++ b/asm.rb
@@ -16,13 +16,9 @@ PROG = [
   0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # 94    p_filesz: 0x00011E02, (size in bytes of the segment in the file)
   0x00, 0x00, 0xC0, 0x7F, 0x00, 0x00, 0x00, 0x00, # 102   p_memsz:  0x7FC00000, (size in bytes of the segment in memory)
   0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # 112
-
-#  0x48, 0xc7, 0xc0, 0x3C, 0x00, 0x00, 0x00,             # mov    $0x3c,%rax
-#  0x48, 0x31, 0xff,                                     # xor    %rdi,%rdi
-#  0x0f, 0x05,                                           # syscall
 ]
 
-Word = Struct.new(:name, :flags, :code)
+Word = Struct.new(:name, :addr, :flags, :code)
 IMM = 1
 
 class Integer
@@ -36,11 +32,11 @@ def pop(); $stack.pop(); end
 def do_word(code); code.each{|w| w.call() }; end
 def word(name, flags, code)
   code = code.map{|w| $words[w].code }
-  $words[name] = Word.new(name, flags, lambda { do_word(code) })
+  $words[name] = Word.new(name, nil, flags, lambda { do_word(code) })
 end
 
 def builtin(name, &code)
-  $words[name] = Word.new(name, 0, code)
+  $words[name] = Word.new(name, nil, 0, code)
 end
 
 def call(word)
@@ -323,40 +319,63 @@ builtin('word') do
 end
 
 builtin('variable') do
-  offset = base_offset()
   call('word')
   name = pop()
 
-  allocation = (3 + ((name.length + 1) / 8.0).ceil) * 8
-  value_addr = (offset + PROG.length)
-  code_addr  = offset + (allocation * 8)
+  # allocate value slot
+  pack64(0)
+
+  offset = base_offset()
+  here = PROG.length
+
+  allocation = (2 + ((name.length + 1) / 8.0).ceil) * 8
+  value_addr = (here - 8)
+  code_addr  = here + allocation
+
+  pack64(code_addr)             # CODE ADDR
+  if $words['latest']
+    pack64($words['latest'].addr)
+  else
+    pack64(0)
+  end
 
-  pack64(0)             # VALUE
-  pack64(code_addr)     # CODE ADDR
-  pack64(0)             # LINK - TODO: actually link to latest
-  pack8(name.length)    # NAME LEN
-  packBytes(name.bytes) # NAME
+  pack8(name.length)            # NAME LEN
+  packBytes(name.bytes)         # NAME
   packPadding(PROG.length % 8)
 
   mov_imm(value_addr, 0)              # load address
   packBytes([0x48, 0x8D, 0x6D, 0x08]) # lea 0x8(%rbp),%rbp
   packBytes([0x48, 0x89, 0x45, 0x00]) # mov %rax,(%rbp)
   packPadding(PROG.length % 8)
+
+  $words[name] = Word.new(name, here + offset, 0, 0)
+  $words['latest'].addr = here + offset
 end
 
 builtin('code') do
-  offset = base_offset()
   call('word')
   name = pop()
 
+  offset = base_offset()
+  here = PROG.length
+
   allocation = (2 + ((name.length + 1) / 8.0).ceil) * 8
-  code_addr  = offset + (allocation * 8)
+  value_addr = (here - 8)
+  code_addr  = here + allocation
 
-  pack64(code_addr)     # CODE ADDR
-  pack64(0)             # LINK - TODO: actually link to latest
-  pack8(name.length)    # NAME LEN
-  packBytes(name.bytes) # NAME
+  pack64(code_addr)             # CODE ADDR
+  if $words['latest']
+    pack64($words['latest'].addr)
+  else
+    pack64(0)
+  end
+
+  pack8(name.length)            # NAME LEN
+  packBytes(name.bytes)         # NAME
   packPadding(PROG.length % 8)
+
+  $words[name] = Word.new(name, here + offset, 0, 0)
+  $words['latest'].addr = here + offset
 end
 
 builtin('end-code') do
diff --git a/asm.s b/asm.s
index c848cac9aff4506401e552706f58d962eda3fd88..0d6aa47f9a5791586c0b15dc351af6bd1c4196dc 100644 (file)
--- a/asm.s
+++ b/asm.s
@@ -29,6 +29,11 @@ variable R0
 # DEFINE BUILTIN WORDS
 # ----------------------------------------
 
+code dummy
+  60 rax load-imm
+  rax push-reg
+end-code
+
 # quit:
 # Loop Forever
 #   r0