Skip to content

Commit efa2dae

Browse files
committed
Fix empty list eval in step2 for most languages.
I think the only remaining ones are ada, elisp, factor, and rust.
1 parent a26c256 commit efa2dae

36 files changed

+79
-18
lines changed

bash/step2_eval.sh

+1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ EVAL () {
4848
EVAL_AST "${ast}" "${env}"
4949
return
5050
fi
51+
_empty? "${ast}" && r="${ast}" && return
5152

5253
# apply list
5354
EVAL_AST "${ast}" "${env}"

clojure/src/step2_eval.clj

+4-2
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,13 @@
3232
(eval-ast ast env)
3333

3434
;; apply list
35-
;; indented to match later steps
35+
;; indented to match later steps
36+
(if (empty? ast)
37+
ast
3638
(let [el (eval-ast ast env)
3739
f (first el)
3840
args (rest el)]
39-
(apply f args))))
41+
(apply f args)))))
4042

4143
;; print
4244
(defn PRINT [exp] (pr-str exp))

coffee/step2_eval.coffee

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ eval_ast = (ast, env) ->
2121
EVAL = (ast, env) ->
2222
#console.log "EVAL:", printer._pr_str ast
2323
if !types._list_Q ast then return eval_ast ast, env
24+
if ast.length == 0 then return ast
2425

2526
# apply list
2627
[f, args...] = eval_ast ast, env

crystal/step2_eval.cr

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ module Mal
5353
def eval(t, env)
5454
Mal::Type.new case ast = t.unwrap
5555
when Mal::List
56-
eval_error "empty list" if ast.empty?
56+
return gen_type Mal::List if ast.empty?
5757

5858
f = eval_ast(ast.first, env)
5959
ast.shift(1)

d/step2_eval.d

+4
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ MalType EVAL(MalType ast, Env env)
5757
{
5858
return eval_ast(ast, env);
5959
}
60+
if ((cast(MalList) ast).elements.length == 0)
61+
{
62+
return ast;
63+
}
6064

6165
auto el = verify_cast!MalList(eval_ast(ast, env));
6266
auto fobj = verify_cast!MalBuiltinFunc(el.elements[0]);

elixir/lib/mix/tasks/step2_eval.ex

+1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ defmodule Mix.Tasks.Step2Eval do
4646
Mal.Reader.read_str(input)
4747
end
4848

49+
defp eval({:list, [], _} = empty_ast, env), do: empty_ast
4950
defp eval({:list, ast, meta}, env), do: eval_list(ast, env, meta)
5051
defp eval(ast, env), do: eval_ast(ast, env)
5152

es6/step2_eval.js

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ const eval_ast = (ast, env) => {
3232

3333
const EVAL = (ast, env) => {
3434
if (!_list_Q(ast)) { return eval_ast(ast, env) }
35+
if (ast.length === 0) { return ast }
3536

3637
const [f, ...args] = eval_ast(ast, env)
3738
return f(...args)

forth/step2_eval.fs

+6-2
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,12 @@ drop
7777

7878
MalList
7979
extend mal-eval { env list -- val }
80-
env list MalList/start @ @ eval
81-
env list rot eval-invoke ;;
80+
list MalList/count @ 0= if
81+
list
82+
else
83+
env list MalList/start @ @ eval
84+
env list rot eval-invoke
85+
endif ;;
8286
drop
8387

8488
MalVector

fsharp/step2_eval.fs

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ module REPL
1111
| node -> node
1212

1313
and eval env = function
14+
| List(_, []) as emptyList -> emptyList
1415
| List(_, _) as node ->
1516
let resolved = node |> eval_ast env
1617
match resolved with

go/src/core/core.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ func empty_Q(a []MalType) (MalType, error) {
235235
case nil:
236236
return true, nil
237237
default:
238-
return nil, errors.New("Count called on non-sequence")
238+
return nil, errors.New("empty? called on non-sequence")
239239
}
240240
}
241241

@@ -250,7 +250,7 @@ func count(a []MalType) (MalType, error) {
250250
case nil:
251251
return 0, nil
252252
default:
253-
return nil, errors.New("Count called on non-sequence")
253+
return nil, errors.New("count called on non-sequence")
254254
}
255255
}
256256

go/src/step2_eval/step2_eval.go

+4
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@ func EVAL(ast MalType, env map[string]MalType) (MalType, error) {
7979
return eval_ast(ast, env)
8080
}
8181

82+
if len(ast.(List).Val) == 0 {
83+
return ast, nil
84+
}
85+
8286
// apply list
8387
el, e := eval_ast(ast, env)
8488
if e != nil {

groovy/step2_eval.groovy

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ eval_ast = { ast, env ->
3232

3333
EVAL = { ast, env ->
3434
if (! types.list_Q(ast)) return eval_ast(ast, env)
35+
if (ast.size() == 0) return ast
3536

3637
def el = eval_ast(ast, env)
3738
def (f, args) = [el[0], el[1..-1]]

guile/step2_eval.scm

+1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646

4747
(define (EVAL ast env)
4848
(match ast
49+
(() ast)
4950
((? list?) (eval_func ast env))
5051
(else (eval_ast ast env))))
5152

haskell/step2_eval.hs

+2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ eval_ast ast@(MalHashMap lst m) env = do
3131
eval_ast ast env = return ast
3232

3333
apply_ast :: MalVal -> (Map.Map String MalVal) -> IOThrows MalVal
34+
apply_ast ast@(MalList [] _) env = do
35+
return ast
3436
apply_ast ast@(MalList _ _) env = do
3537
el <- eval_ast ast env
3638
case el of

haxe/Step2_eval.hx

+3
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ class Step2_eval {
3737
if (!list_Q(ast)) { return eval_ast(ast, env); }
3838

3939
// apply
40+
var alst = switch (ast) { case MalList(lst): lst; case _: []; }
41+
if (alst.length == 0) { return ast; }
42+
4043
var el = eval_ast(ast, env);
4144
var lst = switch (el) { case MalList(lst): lst; case _: []; }
4245
var a0 = lst[0], args = lst.slice(1);

io/step2_eval.io

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ eval_ast := method(ast, env,
2121

2222
EVAL := method(ast, env,
2323
if(ast type != "MalList", return(eval_ast(ast, env)))
24+
if(ast isEmpty, return ast)
2425
el := eval_ast(ast, env)
2526
f := el at(0)
2627
args := el rest

js/step2_eval.js

+3
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ function _EVAL(ast, env) {
3636
if (!types._list_Q(ast)) {
3737
return eval_ast(ast, env);
3838
}
39+
if (ast.length === 0) {
40+
return ast;
41+
}
3942

4043
// apply list
4144
var el = eval_ast(ast, env), f = el[0];

julia/step2_eval.jl

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ end
2525

2626
function EVAL(ast, env)
2727
if !isa(ast, Array) return eval_ast(ast, env) end
28+
if isempty(ast) return ast end
2829

2930
# apply
3031
el = eval_ast(ast, env)

kotlin/src/mal/step2_eval.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package mal
33
fun read(input: String?): MalType = read_str(input)
44

55
fun eval(ast: MalType, env: Map<String, MalType>): MalType =
6-
if (ast is MalList) {
6+
if (ast is MalList && ast.count() > 0) {
77
val evaluated = eval_ast(ast, env) as ISeq
88
if (evaluated.first() !is MalFunction) throw MalException("cannot execute non-function")
99
(evaluated.first() as MalFunction).apply(evaluated.rest())

lua/step2_eval.lua

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ end
3939
function EVAL(ast, env)
4040
--print("EVAL: "..printer._pr_str(ast,true))
4141
if not types._list_Q(ast) then return eval_ast(ast, env) end
42+
if #ast == 0 then return ast end
4243
local args = eval_ast(ast, env)
4344
local f = table.remove(args, 1)
4445
return f(unpack(args))

make/step2_eval.mk

+3-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@ define EVAL
4949
$(strip $(if $(__ERROR),,\
5050
$(and $(EVAL_DEBUG),$(info EVAL: $(call _pr_str,$(1))))\
5151
$(if $(call _list?,$(1)),\
52-
$(strip $(call EVAL_INVOKE,$(1),$(2))),\
52+
$(if $(call _EQ,0,$(call _count,$(1))),\
53+
$(1),\
54+
$(strip $(call EVAL_INVOKE,$(1),$(2)))),\
5355
$(call EVAL_AST,$(1),$(2)))))
5456
endef
5557

mal/step2_eval.mal

+6-4
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,12 @@
2828
(eval-ast ast env)
2929

3030
;; apply list
31-
(let* [el (eval-ast ast env)
32-
f (first el)
33-
args (rest el)]
34-
(apply f args))))))
31+
(if (empty? ast)
32+
ast
33+
(let* [el (eval-ast ast env)
34+
f (first el)
35+
args (rest el)]
36+
(apply f args)))))))
3537

3638

3739
;; print

miniMAL/step2_eval.json

+6-4
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,12 @@
3131
["def", "EVAL", ["fn", ["ast", "env"],
3232
["if", ["not", ["list?", "ast"]],
3333
["eval-ast", "ast", "env"],
34-
["let", ["el", ["eval-ast", "ast", "env"],
35-
"f", ["first", "el"],
36-
"args", ["rest", "el"]],
37-
["apply", "f", "args"]]]]],
34+
["if", ["empty?", "ast"],
35+
"ast",
36+
["let", ["el", ["eval-ast", "ast", "env"],
37+
"f", ["first", "el"],
38+
"args", ["rest", "el"]],
39+
["apply", "f", "args"]]]]]],
3840

3941
["def", "PRINT", ["fn", ["exp"],
4042
["pr-str", "exp", true]]],

nim/step2_eval.nim

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ proc eval_ast(ast: MalType, env: Table[string, MalType]): MalType =
2424
proc eval(ast: MalType, env: Table[string, MalType]): MalType =
2525
case ast.kind
2626
of List:
27+
if ast.list.len == 0: return ast
2728
let el = ast.eval_ast(env)
2829
el.list[0].fun(el.list[1 .. ^1])
2930
else:

perl/step2_eval.pl

+1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ sub EVAL {
5757
}
5858

5959
# apply list
60+
if (scalar(@{$ast->{val}}) == 0) { return $ast; }
6061
my $el = eval_ast($ast, $env);
6162
my $f = $el->nth(0);
6263
return &{ $f }($el->rest());

php/step2_eval.php

+3
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ function MAL_EVAL($ast, $env) {
3737
if (!_list_Q($ast)) {
3838
return eval_ast($ast, $env);
3939
}
40+
if ($ast->count() === 0) {
41+
return $ast;
42+
}
4043

4144
// apply list
4245
$el = eval_ast($ast, $env);

process/guide.md

+1
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,7 @@ repl_env = {'+': lambda a,b: a+b,
515515
* Modify `EVAL` to check if the first parameter `ast` is a list.
516516
* `ast` is not a list: then return the result of calling `eval_ast`
517517
on it.
518+
* `ast` is a empty list: return ast unchanged.
518519
* `ast` is a list: call `eval_ast` to get a new evaluated list. Take
519520
the first item of the evaluated list and call it as function using
520521
the rest of the evaluated list as its arguments.

ps/step2_eval.ps

82 Bytes
Binary file not shown.

python/step2_eval.py

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ def EVAL(ast, env):
3333
return eval_ast(ast, env)
3434

3535
# apply list
36+
if len(ast) == 0: return ast
3637
el = eval_ast(ast, env)
3738
f = el[0]
3839
return f(*el[1:])

r/step2_eval.r

+3
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ EVAL <- function(ast, env) {
3333
}
3434

3535
# apply list
36+
if (length(ast) == 0) {
37+
return(ast)
38+
}
3639
el <- eval_ast(ast, env)
3740
f <- el[[1]]
3841
return(do.call(f,el[-1]))

racket/step2_eval.rkt

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
[else ast]))
2222

2323
(define (EVAL ast env)
24-
(if (not (list? ast))
24+
(if (or (not (list? ast)) (empty? ast))
2525
(eval-ast ast env)
2626

2727
(let* ([el (eval-ast ast env)]

rpython/step2_eval.py

+1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ def EVAL(ast, env):
4242
return eval_ast(ast, env)
4343

4444
# apply list
45+
if len(ast) == 0: return ast
4546
el = eval_ast(ast, env)
4647
f = el.values[0]
4748
if isinstance(f, MalFunc):

ruby/step2_eval.rb

+3
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ def EVAL(ast, env)
3333
if not ast.is_a? List
3434
return eval_ast(ast, env)
3535
end
36+
if ast.empty?
37+
return ast
38+
end
3639

3740
# apply list
3841
el = eval_ast(ast, env)

scala/step2_eval.scala

+2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ object step2_eval {
2525
return eval_ast(ast, env)
2626

2727
// apply list
28+
if (ast.asInstanceOf[MalList].value.length == 0)
29+
return ast
2830
eval_ast(ast, env).asInstanceOf[MalList].value match {
2931
case f :: el => {
3032
var fn: List[Any] => Any = null

tcl/step2_eval.tcl

+4
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ proc EVAL {ast env} {
4646
if {![list_q $ast]} {
4747
return [eval_ast $ast $env]
4848
}
49+
set a0 [lindex [obj_val $ast] 0]
50+
if {$a0 == ""} {
51+
return $ast
52+
}
4953
set lst_obj [eval_ast $ast $env]
5054
set lst [obj_val $lst_obj]
5155
set f [lindex $lst 0]

vimscript/step2_eval.vim

+3
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ function EVAL(ast, env)
4545
if !ListQ(a:ast)
4646
return EvalAst(a:ast, a:env)
4747
end
48+
if EmptyQ(a:ast)
49+
return a:ast
50+
endif
4851

4952
" apply list
5053
let el = EvalAst(a:ast, a:env)

0 commit comments

Comments
 (0)