Rewrite expression to use list instead of list node.

This commit is contained in:
Simon Forman 2022-09-14 14:36:29 -07:00
parent 9e5d699b0f
commit 129a5f776d
1 changed files with 22 additions and 30 deletions

View File

@ -1,7 +1,6 @@
import rdstdin, strutils import rdstdin, strutils
import bigints, fp import bigints, fp
# TODO: rewrite expression to use list instead of list node.
type type
@ -191,25 +190,23 @@ concatenating them.
]# ]#
proc push_quote(quote: JoyType, expression: JoyType): JoyType = proc push_quote(quote: JoyType, expression: JoyListType): JoyListType =
#[ #[
Put the quoted program NODE onto the stack-of-stacks. Put the quoted program NODE onto the stack-of-stacks.
]# ]#
let ql = as_list(quote) if as_list(quote).isEmpty:
if ql.isEmpty:
return expression return expression
let el = as_list(expression) return quote ^^ expression
return JoyType(kind: joyList, listVal: (quote ^^ el))
proc push_quote_list(quote: JoyListType, expression: JoyType): JoyType = proc push_quote_list(quote: JoyListType, expression: JoyListType): JoyListType =
#[ #[
Put the quoted program LIST onto the stack-of-stacks. Put the quoted program LIST onto the stack-of-stacks.
]# ]#
return push_quote(JoyType(kind: joyList, listVal: quote), expression) return push_quote(JoyType(kind: joyList, listVal: quote), expression)
proc next_term(expression: JoyType): (JoyType, JoyType) = proc next_term(expression: JoyListType): (JoyType, JoyListType) =
#[ #[
Return the next term from the expression and the new expression. Return the next term from the expression and the new expression.
Raises ValueError if called on an empty expression. Raises ValueError if called on an empty expression.
@ -218,18 +215,13 @@ proc next_term(expression: JoyType): (JoyType, JoyType) =
return item, push_quote(quote, expression) return item, push_quote(quote, expression)
]# ]#
let el = as_list(expression) ## JoyListType let (eheadl, etail) = pop_list(expression)
let ehead = el.head ## JoyType
let eheadl = as_list(ehead) ## JoyListType
let item = eheadl.head ## JoyType let item = eheadl.head ## JoyType
let quote = eheadl.tail ## JoyListType let quote = eheadl.tail ## JoyListType
if quote.isEmpty: if quote.isEmpty:
let t = JoyType(kind: joyList, listVal: el.tail) return (item, etail)
return (item, t)
else: else:
let q = JoyType(kind: joyList, listVal: quote) return (item, push_list(quote, etail))
let t = JoyType(kind: joyList, listVal: (q ^^ el.tail))
return (item, t)
#██████╗ █████╗ ██████╗ ███████╗███████╗██████╗ #██████╗ █████╗ ██████╗ ███████╗███████╗██████╗
@ -240,7 +232,7 @@ proc next_term(expression: JoyType): (JoyType, JoyType) =
#╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚══════╝╚═╝ ╚═╝ #╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚══════╝╚═╝ ╚═╝
proc text_to_expression(text: string): JoyType = proc text_to_expression(text: string): JoyListType =
#[ #[
Convert a string to a Joy expression. Convert a string to a Joy expression.
@ -284,7 +276,7 @@ proc text_to_expression(text: string): JoyType =
if stack.len() != 0: if stack.len() != 0:
raise newException(ParseError, "Unclosed bracket.") raise newException(ParseError, "Unclosed bracket.")
JoyType(kind: joyList, listVal: frame.asList) frame.asList
#██████╗ ██████╗ ██╗███╗ ██╗████████╗███████╗██████╗ #██████╗ ██████╗ ██╗███╗ ██╗████████╗███████╗██████╗
@ -323,8 +315,8 @@ proc print_stack*(stack: JoyListType): string =
# ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚═════╝ ╚═╝╚═╝ ╚═══╝╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝ # ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚═════╝ ╚═╝╚═╝ ╚═══╝╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝
proc branch(stack: JoyListType, expression: JoyType, dictionary: JoyMapType): ( proc branch(stack: JoyListType, expression: JoyListType, dictionary: JoyMapType): (
JoyListType, JoyType, JoyMapType) = JoyListType, JoyListType, JoyMapType) =
let (true_body_node, s0) = pop_list_node(stack) let (true_body_node, s0) = pop_list_node(stack)
let (false_body_node, s1) = pop_list_node(s0) let (false_body_node, s1) = pop_list_node(s0)
let (flag, s2) = pop_bool(s1) let (flag, s2) = pop_bool(s1)
@ -343,13 +335,13 @@ proc branch(stack: JoyListType, expression: JoyType, dictionary: JoyMapType): (
]# ]#
proc clear(stack: JoyListType, expression: JoyType, dictionary: JoyMapType): ( proc clear(stack: JoyListType, expression: JoyListType, dictionary: JoyMapType): (
JoyListType, JoyType, JoyMapType) = JoyListType, JoyListType, JoyMapType) =
return (empty_list.listVal, expression, dictionary) return (empty_list.listVal, expression, dictionary)
proc concat(stack: JoyListType, expression: JoyType, dictionary: JoyMapType): ( proc concat(stack: JoyListType, expression: JoyListType, dictionary: JoyMapType): (
JoyListType, JoyType, JoyMapType) = JoyListType, JoyListType, JoyMapType) =
let (tos, s0) = pop_list(stack) let (tos, s0) = pop_list(stack)
let (second, s1) = pop_list(s0) let (second, s1) = pop_list(s0)
return (push_list((second ++ tos), s1), expression, dictionary) return (push_list((second ++ tos), s1), expression, dictionary)
@ -368,8 +360,8 @@ proc concat(stack: JoyListType, expression: JoyType, dictionary: JoyMapType): (
# it looks up in the dictionary. # it looks up in the dictionary.
proc joy_eval(sym: string, stack: JoyListType, expression: JoyType, proc joy_eval(sym: string, stack: JoyListType, expression: JoyListType,
dictionary: JoyMapType): (JoyListType, JoyType, JoyMapType) = dictionary: JoyMapType): (JoyListType, JoyListType, JoyMapType) =
case sym case sym
of "add": of "add":
@ -435,14 +427,14 @@ proc joy_eval(sym: string, stack: JoyListType, expression: JoyType,
return (stack, expression, dictionary) return (stack, expression, dictionary)
proc joy(stack: JoyListType, expression: JoyType, dictionary: JoyMapType): ( proc joy(stack: JoyListType, expression: JoyListType, dictionary: JoyMapType): (
JoyListType, JoyMapType) = JoyListType, JoyMapType) =
var s = stack var s = stack
var d = dictionary var d = dictionary
var e = push_quote(expression, empty_list) var e = push_quote_list(expression, empty_list.listVal)
var term: JoyType var term: JoyType
while not e.listVal.isEmpty: while not e.isEmpty:
(term, e) = next_term(e) (term, e) = next_term(e)
#echo pr_str(term) #echo pr_str(term)
case term.kind case term.kind
@ -465,7 +457,7 @@ proc joy(stack: JoyListType, expression: JoyType, dictionary: JoyMapType): (
var s = empty_list.listVal var s = empty_list.listVal
var d = newMap[string, JoyListType]() var d = newMap[string, JoyListType]()
var exp: JoyType var exp: JoyListType
while true: while true:
try: try:
exp = text_to_expression(readLineFromStdin("joy? ")) exp = text_to_expression(readLineFromStdin("joy? "))