Added #foo.bar macro to mean <. foo 'bar .>, improved stack word output.

This commit is contained in:
Russ Olsen 2020-04-25 16:54:45 -04:00
parent e1b1c4ee24
commit 638d50b100
8 changed files with 38 additions and 24 deletions

View file

@ -26,7 +26,7 @@ class Forth:
'*source*': const_f(__file__), '*source*': const_f(__file__),
'true': const_f(True), 'true': const_f(True),
'false': const_f(False), 'false': const_f(False),
'nil': const_f(None), 'None': const_f(None),
'0': const_f(0), '0': const_f(0),
'1': const_f(1), '1': const_f(1),
'2': const_f(2)} '2': const_f(2)}
@ -81,12 +81,16 @@ class Forth:
self.compile_token(token) self.compile_token(token)
def macro_expand_token(self, token): def macro_expand_token(self, token):
if len(token) <= 0: if len(token) <= 0 or token[0] != '#':
return [token]
if token[0] != '#':
return [token] return [token]
tag = token[1:] tag = token[1:]
return self.py_evaluate('macroexpand', tag) parts = tag.split('.')
result = [ '<.', parts[0] ]
for part in parts[1::]:
result.append("'" + part)
result.append('.>')
return result
def macro_expand_tokens(self, tokens): def macro_expand_tokens(self, tokens):
results = [] results = []
@ -101,10 +105,10 @@ class Forth:
raise ValueError(f'No such namespace: {ns_name}') raise ValueError(f'No such namespace: {ns_name}')
def make_namespace(self, ns_name, initial_defs={}, refers=[]): def make_namespace(self, ns_name, initial_defs={}, refers=[]):
print(f'New namespace {ns_name} {refers}') #print(f'New namespace {ns_name} {refers}')
result = Namespace(ns_name, initial_defs, refers) result = Namespace(ns_name, initial_defs, refers)
self.namespaces[ns_name] = result self.namespaces[ns_name] = result
print(f'Returning {result}') #print(f'Returning {result}')
return result return result
def execute_file(self, fpath): def execute_file(self, fpath):

View file

@ -11,7 +11,6 @@ def is_space(ch):
class Tokenizer: class Tokenizer:
def __init__(self, forth): def __init__(self, forth):
self.forth = forth self.forth = forth
print("Tokenizer:", self.forth)
def tokenize(self, s): def tokenize(self, s):
raw_tokens = self.raw_tokenize(s) raw_tokens = self.raw_tokenize(s)

View file

@ -1,5 +1,3 @@
"List" p
\ Index into the x'th item. \ Index into the x'th item.
: [x] (col key -- value) 1 ->list '__getitem__ .!! ; : [x] (col key -- value) 1 ->list '__getitem__ .!! ;
@ -26,6 +24,10 @@
swap nil slice \ Make the n..None slice. swap nil slice \ Make the n..None slice.
[x] [x]
; ;
: repeat (n x -- list-of-x-repeated-n-times)
1 ->list *
;
: rest (list -- all-but-first) 1 swap drop ; : rest (list -- all-but-first) 1 swap drop ;
: rrest (list -- rest-of-rest) rest rest ; : rrest (list -- rest-of-rest) rest rest ;

View file

@ -1,9 +1,5 @@
class Namespace: class Namespace:
def __init__(self, name, initial_contents={}, refers=[]): def __init__(self, name, initial_contents={}, refers=[]):
print('name', name)
print('initial contents', initial_contents)
print('refers', refers)
print('===')
self.name = name self.name = name
self.contents = initial_contents.copy() self.contents = initial_contents.copy()
self.refers = refers.copy() self.refers = refers.copy()

View file

@ -19,9 +19,12 @@ class Stack:
return result return result
def __iter__(self): def __iter__(self):
for i in range(self.top, -1, -1): for i in range(0, self.top+1):
yield self.stack[i] yield self.stack[i]
def empty(self):
return self.top == -1
def peek(self): def peek(self):
return self.stack[self.top] return self.stack[self.top]

View file

@ -1,4 +1,4 @@
"Executing " dot *source* dot nl \ "Executing " dot *source* dot nl
\ Pull in libs. \ Pull in libs.
@ -13,6 +13,7 @@
\ Basic aliases \ Basic aliases
'None 'nil alias
'dot '. alias 'dot '. alias
'colon ': alias 'colon ': alias
'semi '; alias 'semi '; alias
@ -112,6 +113,10 @@
: getattr ( obj attr -- attr-value ) swap 2 ->list builtins.getattr !! ; : getattr ( obj attr -- attr-value ) swap 2 ->list builtins.getattr !! ;
: .!! (obj args method-name -- result) tbm getattr !! ; : .!! (obj args method-name -- result) tbm getattr !! ;
: .!!0 (obj method-name -- result ) [] swap .!! ;
: .!!1 (obj arg method-name -- result ) swap 1 ->list swap .!! ;
: .!!2 (obj a1 a2 method-name -- result ) swap 2 ->list swap .!! ;
: .!!3 (obj a1 a2 a3 method-name -- result ) swap 3 ->list swap .!! ;
"string.sf" source "string.sf" source
"list.sf" source "list.sf" source

View file

@ -1,5 +1,3 @@
"String" p
: split (delimit str -- tokens) 2 ->list <. builtins.str 'split .> !! ; : split (delimit str -- tokens) 2 ->list <. builtins.str 'split .> !! ;
: dot-split (str -- tokens) "." swap split ; : dot-split (str -- tokens) "." swap split ;

View file

@ -44,9 +44,9 @@ def w_no_op(f, i):
return i+1 return i+1
def w_enlist(f, i): def w_enlist(f, i):
print("Enlist!") # print("Enlist!")
x = f.stack.pop() x = f.stack.pop()
print("Popped", x) # print("Popped", x)
f.stack.push([x]) f.stack.push([x])
return i+1 return i+1
@ -313,7 +313,7 @@ def w_def(f, i):
value = f.stack.pop() value = f.stack.pop()
name = f.stack.pop() name = f.stack.pop()
f.defvar(name, value) f.defvar(name, value)
print('name', name, 'value', value) # print('name', name, 'value', value)
return i+1 return i+1
def w_gt(f, i): def w_gt(f, i):
@ -379,6 +379,13 @@ def w_dot(f, i):
print(a, end='') print(a, end='')
return i+1 return i+1
def w_splat(f, i):
l = f.stack.pop()
l.reverse()
for x in l:
f.stack.push(x)
return i+1
def w_dup(f, i): def w_dup(f, i):
x = f.stack.peek() x = f.stack.peek()
f.stack.push(x) f.stack.push(x)
@ -569,8 +576,8 @@ def w_idump(f, i):
w_idump.__dict__['immediate'] = True w_idump.__dict__['immediate'] = True
def w_stack(f, i): def w_stack(f, i):
print("::top::") print("Stack:", end=' ')
for x in f.stack: for x in f.stack:
print(f'{x}') print(f'{repr(x)}', end=' ')
print("::bottom::") print()
return i+1 return i+1