Skip to content

Commit

Permalink
Add let and let*
Browse files Browse the repository at this point in the history
  • Loading branch information
WyattBlue committed Jul 26, 2023
1 parent ac091a3 commit f1b4f11
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 26 deletions.
4 changes: 2 additions & 2 deletions auto_editor/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
__version__ = "23.28.1"
version = "23w28a"
__version__ = "23.29.1"
version = "23w29a-dev"
61 changes: 45 additions & 16 deletions auto_editor/lang/palet.py
Original file line number Diff line number Diff line change
Expand Up @@ -904,7 +904,7 @@ def syn_set(env: Env, node: list) -> None:

name = node[1].val
if name not in env:
raise MyError(f"{node[0]}: cannot set variable {name} before definition")
raise MyError(f"{node[0]}: cannot set variable '{name}' before definition")
env[name] = my_eval(env, node[2])
return None

Expand Down Expand Up @@ -1040,24 +1040,55 @@ def syn_rename(env: Env, node: list) -> None:
del env[first.val]


class PaletObject:
__slots__ = "attributes"
def syn_let(env: Env, node: list) -> Any:
if len(node) < 2:
raise MyError(f"{node[0]}: Arity mismatch: Expected at least 1 term")

def __init__(self, attrs: dict[str, Any]):
self.attributes = attrs
if type(node[1]) is Sym:
raise MyError(f"{node[0]}: Named-let form is not supported")

for var_ids in node[1]:
if len(var_ids) != 2:
raise MyError(f"{node[0]}: Expected two terms: `id` and `val-expr`")

is_obj = Contract(
"object?",
lambda v: type(v) is str or isinstance(v, (list, Proc, PaletObject)),
)
new_maps: dict[str, Any] = {}
for var, val in node[1]:
if type(var) is not Sym:
raise MyError(f"{node[0]}: Expected symbol for `id` term")
new_maps[var.val] = my_eval(env, val)

inner_env = Env(new_maps, env)
for item in node[2:-1]:
my_eval(inner_env, item)
return my_eval(inner_env, node[-1])


def syn_let_star(env: Env, node: list) -> Any:
if len(node) < 2:
raise MyError(f"{node[0]}: Arity mismatch: Expected at least 1 term")

for var_ids in node[1]:
if len(var_ids) != 2:
raise MyError(f"{node[0]}: Expected two terms: `id` and `val-expr`")

inner_env = Env({}, env)

for var, val in node[1]:
if type(var) is not Sym:
raise MyError(f"{node[0]}: Expected symbol for `id` term")
inner_env[var.val] = my_eval(inner_env, val)

for item in node[2:-1]:
my_eval(inner_env, item)
return my_eval(inner_env, node[-1])


is_obj = Contract("object?", lambda v: type(v) is str or isinstance(v, (list, Proc)))


def get_attrs(obj: Any) -> dict[str, Any]:
if type(obj) is str:
return {
"@name": "string",
"@len": Proc("@len", obj.__len__, (0, 0)),
"split": Proc("split", obj.split, (0, 1), [is_str]),
"strip": Proc("strip", obj.strip, (0, 0)),
"repeat": Proc("repeat", lambda a: obj * a, (1, 1), [is_int]),
Expand All @@ -1070,16 +1101,12 @@ def get_attrs(obj: Any) -> dict[str, Any]:
}
if isinstance(obj, list):
return {
"@name": "vector",
"@len": Proc("@len", obj.__len__, (0, 0)),
"repeat": Proc("repeat", lambda a: obj * a, (1, 1), [is_int]),
"pop": Proc("pop", obj.pop, (0, 0)),
"sort": Proc("sort", lambda: sorted(obj), (0, 0)),
"sort!": Proc("sort!", obj.sort, (0, 0)),
}
if isinstance(obj, PaletObject):
return obj.attributes
raise MyError("")
raise MyError("Not an object!")


def attr(env: Env, node: list) -> Any:
Expand Down Expand Up @@ -1172,6 +1199,8 @@ def my_eval(env: Env, node: object) -> Any:
"quote": Syntax(syn_quote),
"if": Syntax(syn_if),
"when": Syntax(syn_when),
"let": Syntax(syn_let),
"let*": Syntax(syn_let_star),
# loops
"for": Syntax(syn_for),
# contracts
Expand Down
19 changes: 18 additions & 1 deletion resources/scripts/scope.pt
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,21 @@
(outer 13)
(assert (not (var-exists? 'a)))
(assert (not (var-exists? 'b)))
(assert (not (var-exists? 'c)))
(assert (not (var-exists? 'c)))

; Test `let` and `let*`

(assert (equal? (let ([x 5]) x) 5))
(assert (not (var-exists? 'x)))

(assert (equal?
(let ([x 5])
(let ([x 2] [y x]) #(y x))
)
#(5 2)
))

(assert (equal?
(let* ([x 1] [y (+ x 1)]) #(y x))
#(2 1)
))
4 changes: 2 additions & 2 deletions site/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,9 +187,9 @@ def build_var_sig(sigs: list[str | tuple]) -> str:
with open("paletdoc.pt", "r") as sourcefile:
source = sourcefile.read()[:]

canonical_env = deepcopy(env)
canonical_env = deepcopy(env.data)
result = interpret(env, Parser(Lexer("paletdoc.pt", source)))
doc = env["doc"].copy()
doc = env.data["doc"].copy()

for category, somethings in doc.items():
file.write(f'<h2 class="left">{category}</h2>\n')
Expand Down
22 changes: 17 additions & 5 deletions site/paletdoc.pt
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,37 @@

(define doc {hash
"Assignment" #[
(syntax "define" "id expr" (text "Set " 'id " to the result of " 'expr "."))
(syntax "define" "id expr" (text "Set "'id" to the result of "'expr"."))
(syntax "set!" "id expr"
(text
"Set " 'id " to the result of " 'expr " if " 'id
" is already defined. If " 'id " is not defined, raise an error."
"Set "'id" to the result of "'expr" if "'id
" is already defined. If "'id" is not defined, raise an error."
)
)
(syntax
"lambda" "args body"
(text
"Produces a procedure that accepts " 'args " arguments and runs "
'body " when called."
"Produces a procedure that accepts "'args" arguments and runs "
'body" when called."
)
)
(syntax "λ" "args body" (text "Clone of " (link 'lambda) "."))
(syntax
"define/c" "(proc-bind [id-binding contract]... )"
(text "Define a procedure with contracts.")
)
(syntax "let" "([id val-expr] ...) body)"
(text "Evaluates the "'val-expr"s left-to-right, creating a new location for each "'id
", and places the values into the locations. It then evaluates the "'body
"s, in which the "'id"s are bound.")
)
(syntax "let*" "([id val-expr] ...) body)"
(text "Like " (link 'let) ", but evaluates the "'val-expr
"s one by one, creating a location for each "'id
" as soon as the value is available. The "'id"s are bound in the remaining "
'val-expr"s as well as in the "'body"."
)
)
]
"Control Flow" #[
(syntax
Expand Down

0 comments on commit f1b4f11

Please sign in to comment.