2018-10-15 00:44:08 +03:00
|
|
|
(module $step5_tco
|
|
|
|
|
|
|
|
(global $repl_env (mut i32) (i32.const 0))
|
|
|
|
|
|
|
|
;; READ
|
|
|
|
(func $READ (param $str i32) (result i32)
|
|
|
|
($read_str $str)
|
|
|
|
)
|
|
|
|
|
|
|
|
;; EVAL
|
|
|
|
(func $EVAL_AST (param $ast i32 $env i32 $skiplast i32) (result i32)
|
2018-11-12 02:55:38 +03:00
|
|
|
(LET $res 0 $val2 0 $val3 0 $type 0 $found 0
|
|
|
|
$ret 0 $empty 0 $current 0)
|
2018-10-15 00:44:08 +03:00
|
|
|
|
2019-01-16 09:13:51 +03:00
|
|
|
(if (global.get $error_type) (return 0))
|
|
|
|
(local.set $type ($TYPE $ast))
|
2018-10-15 00:44:08 +03:00
|
|
|
|
|
|
|
;;($PR_VALUE ">>> EVAL_AST ast: '%s'\n" $ast)
|
|
|
|
|
|
|
|
;;; switch(type)
|
|
|
|
(block $done
|
|
|
|
(block $default (block (block
|
|
|
|
(br_table 2 2 2 2 2 0 1 1 1 2 2 2 2 2 2 2 $type))
|
|
|
|
;; symbol
|
|
|
|
;; found/res returned as hi 32/lo 32 of i64
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $res ($ENV_GET $env $ast))
|
2018-10-15 00:44:08 +03:00
|
|
|
(br $done))
|
|
|
|
;; list, vector, hashmap
|
|
|
|
;; MAP_LOOP_START
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $res ($MAP_LOOP_START $type))
|
2018-10-15 00:44:08 +03:00
|
|
|
;; push MAP_LOOP stack
|
|
|
|
;;; empty = current = ret = res
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $ret $res)
|
|
|
|
(local.set $current $res)
|
|
|
|
(local.set $empty $res)
|
2018-10-15 00:44:08 +03:00
|
|
|
|
|
|
|
(block $done
|
|
|
|
(loop $loop
|
|
|
|
;; check if we are done evaluating the source sequence
|
2018-11-12 02:55:38 +03:00
|
|
|
(br_if $done (i32.eq ($VAL0 $ast) 0))
|
2018-10-15 00:44:08 +03:00
|
|
|
|
|
|
|
(if $skiplast
|
2018-12-09 01:51:16 +03:00
|
|
|
(br_if $done (i32.eqz ($VAL0 ($MEM_VAL0_ptr $ast)))))
|
2018-10-15 00:44:08 +03:00
|
|
|
|
2019-01-16 09:13:51 +03:00
|
|
|
(if (i32.eq $type (global.get $HASHMAP_T))
|
2018-10-15 00:44:08 +03:00
|
|
|
(then
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $res ($EVAL ($MEM_VAL2_ptr $ast) $env)))
|
2018-10-15 00:44:08 +03:00
|
|
|
(else
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $res ($EVAL ($MEM_VAL1_ptr $ast) $env))))
|
|
|
|
(local.set $val2 $res)
|
2018-10-15 00:44:08 +03:00
|
|
|
|
|
|
|
;; if error, release the unattached element
|
2019-01-16 09:13:51 +03:00
|
|
|
(if (global.get $error_type)
|
2018-10-15 00:44:08 +03:00
|
|
|
(then
|
|
|
|
($RELEASE $res)
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $res 0)
|
2018-10-15 00:44:08 +03:00
|
|
|
(br $done)))
|
|
|
|
|
|
|
|
;; for hash-maps, copy the key (inc ref since we are going
|
|
|
|
;; to release it below)
|
2019-01-16 09:13:51 +03:00
|
|
|
(if (i32.eq $type (global.get $HASHMAP_T))
|
2018-10-15 00:44:08 +03:00
|
|
|
(then
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $val3 $val2)
|
|
|
|
(local.set $val2 ($MEM_VAL1_ptr $ast))
|
2018-10-15 00:44:08 +03:00
|
|
|
(drop ($INC_REF $val2))))
|
|
|
|
|
|
|
|
;; MAP_LOOP_UPDATE
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $res ($MAP_LOOP_UPDATE $type $empty $current $val2 $val3))
|
|
|
|
(if (i32.le_u $current (global.get $EMPTY_HASHMAP))
|
2018-10-15 00:44:08 +03:00
|
|
|
;; if first element, set return to new element
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $ret $res))
|
2018-10-15 00:44:08 +03:00
|
|
|
;; update current to point to new element
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $current $res)
|
2018-10-15 00:44:08 +03:00
|
|
|
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $ast ($MEM_VAL0_ptr $ast))
|
2018-10-15 00:44:08 +03:00
|
|
|
|
|
|
|
(br $loop)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
;; MAP_LOOP_DONE
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $res $ret)
|
2018-10-15 00:44:08 +03:00
|
|
|
;; EVAL_AST_RETURN: nothing to do
|
|
|
|
(br $done))
|
|
|
|
;; default
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $res ($INC_REF $ast))
|
2018-10-15 00:44:08 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
$res
|
|
|
|
)
|
|
|
|
|
|
|
|
(func $MAL_GET_A1 (param $ast i32) (result i32)
|
|
|
|
($MEM_VAL1_ptr ($MEM_VAL0_ptr $ast)))
|
|
|
|
(func $MAL_GET_A2 (param $ast i32) (result i32)
|
|
|
|
($MEM_VAL1_ptr ($MEM_VAL0_ptr ($MEM_VAL0_ptr $ast))))
|
|
|
|
(func $MAL_GET_A3 (param $ast i32) (result i32)
|
|
|
|
($MEM_VAL1_ptr ($MEM_VAL0_ptr ($MEM_VAL0_ptr ($MEM_VAL0_ptr $ast)))))
|
|
|
|
|
|
|
|
(func $EVAL (param $orig_ast i32 $orig_env i32) (result i32)
|
2018-11-12 02:55:38 +03:00
|
|
|
(LET $ast $orig_ast
|
|
|
|
$env $orig_env
|
|
|
|
$prev_ast 0 $prev_env 0 $res 0 $el 0
|
|
|
|
$ftype 0 $f_args 0 $f 0 $args 0
|
|
|
|
$a0 0 $a0sym 0 $a1 0 $a2 0)
|
2018-10-15 00:44:08 +03:00
|
|
|
|
|
|
|
(block $EVAL_return
|
|
|
|
(loop $TCO_loop
|
|
|
|
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $f_args 0)
|
|
|
|
(local.set $f 0)
|
|
|
|
(local.set $args 0)
|
2018-10-15 00:44:08 +03:00
|
|
|
|
2019-01-16 09:13:51 +03:00
|
|
|
(if (global.get $error_type)
|
2018-10-15 00:44:08 +03:00
|
|
|
(then
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $res 0)
|
2018-10-15 00:44:08 +03:00
|
|
|
(br $EVAL_return)))
|
|
|
|
|
2018-11-12 00:30:42 +03:00
|
|
|
;;($PR_VALUE ">>> EVAL ast: '%s'\n" $ast)
|
|
|
|
|
2019-01-16 09:13:51 +03:00
|
|
|
(if (i32.ne ($TYPE $ast) (global.get $LIST_T))
|
2018-10-15 00:44:08 +03:00
|
|
|
(then
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $res ($EVAL_AST $ast $env 0))
|
2018-10-15 00:44:08 +03:00
|
|
|
(br $EVAL_return)))
|
|
|
|
|
|
|
|
;; APPLY_LIST
|
|
|
|
(if ($EMPTY_Q $ast)
|
|
|
|
(then
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $res ($INC_REF $ast))
|
2018-10-15 00:44:08 +03:00
|
|
|
(br $EVAL_return)))
|
|
|
|
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $a0 ($MEM_VAL1_ptr $ast))
|
|
|
|
(local.set $a0sym "")
|
|
|
|
(if (i32.eq ($TYPE $a0) (global.get $SYMBOL_T))
|
|
|
|
(local.set $a0sym ($to_String $a0)))
|
2018-10-15 00:44:08 +03:00
|
|
|
|
|
|
|
(if (i32.eqz ($strcmp "def!" $a0sym))
|
|
|
|
(then
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $a1 ($MAL_GET_A1 $ast))
|
|
|
|
(local.set $a2 ($MAL_GET_A2 $ast))
|
|
|
|
(local.set $res ($EVAL $a2 $env))
|
|
|
|
(br_if $EVAL_return (global.get $error_type))
|
2018-10-15 00:44:08 +03:00
|
|
|
|
|
|
|
;; set a1 in env to a2
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $res ($ENV_SET $env $a1 $res))
|
2018-10-15 00:44:08 +03:00
|
|
|
(br $EVAL_return))
|
|
|
|
(else (if (i32.eqz ($strcmp "let*" $a0sym))
|
|
|
|
(then
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $a1 ($MAL_GET_A1 $ast))
|
|
|
|
(local.set $a2 ($MAL_GET_A2 $ast))
|
2018-10-15 00:44:08 +03:00
|
|
|
|
|
|
|
;; create new environment with outer as current environment
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $prev_env $env) ;; save env for later release
|
|
|
|
(local.set $env ($ENV_NEW $env))
|
2018-10-15 00:44:08 +03:00
|
|
|
|
|
|
|
(block $done
|
|
|
|
(loop $loop
|
2018-11-12 02:55:38 +03:00
|
|
|
(br_if $done (i32.eqz ($VAL0 $a1)))
|
2018-10-15 00:44:08 +03:00
|
|
|
;; eval current A1 odd element
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $res ($EVAL ($MEM_VAL1_ptr ($MEM_VAL0_ptr $a1)) $env))
|
2018-10-15 00:44:08 +03:00
|
|
|
|
2019-01-16 09:13:51 +03:00
|
|
|
(br_if $done (global.get $error_type))
|
2018-10-15 00:44:08 +03:00
|
|
|
|
|
|
|
;; set key/value in the let environment
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $res ($ENV_SET $env ($MEM_VAL1_ptr $a1) $res))
|
2018-10-15 00:44:08 +03:00
|
|
|
;; release our use, ENV_SET took ownership
|
|
|
|
($RELEASE $res)
|
|
|
|
|
|
|
|
;; skip to the next pair of a1 elements
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $a1 ($MEM_VAL0_ptr ($MEM_VAL0_ptr $a1)))
|
2018-10-15 00:44:08 +03:00
|
|
|
(br $loop)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
;; release previous environment if not the current EVAL env
|
|
|
|
(if (i32.ne $prev_env $orig_env)
|
|
|
|
(then
|
|
|
|
($RELEASE $prev_env)
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $prev_env 0)))
|
2018-10-15 00:44:08 +03:00
|
|
|
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $ast $a2)
|
2018-10-15 00:44:08 +03:00
|
|
|
(br $TCO_loop))
|
|
|
|
(else (if (i32.eqz ($strcmp "do" $a0sym))
|
|
|
|
(then
|
|
|
|
;; EVAL the rest through second to last
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $el ($EVAL_AST ($MEM_VAL0_ptr $ast) $env 1))
|
|
|
|
(local.set $ast ($LAST $ast))
|
2018-11-12 00:30:42 +03:00
|
|
|
($RELEASE $ast) ;; we already own it via ast
|
2018-10-15 00:44:08 +03:00
|
|
|
($RELEASE $el)
|
|
|
|
(br $TCO_loop))
|
|
|
|
(else (if (i32.eqz ($strcmp "if" $a0sym))
|
|
|
|
(then
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $a1 ($MAL_GET_A1 $ast))
|
|
|
|
(local.set $res ($EVAL $a1 $env))
|
2018-10-15 00:44:08 +03:00
|
|
|
|
2019-01-16 09:13:51 +03:00
|
|
|
(if (global.get $error_type)
|
2018-10-15 00:44:08 +03:00
|
|
|
(then (nop))
|
2019-01-16 09:13:51 +03:00
|
|
|
(else (if (OR (i32.eq $res (global.get $NIL))
|
|
|
|
(i32.eq $res (global.get $FALSE)))
|
2018-10-15 00:44:08 +03:00
|
|
|
(then
|
|
|
|
($RELEASE $res)
|
|
|
|
;; if no false case (A3), return nil
|
|
|
|
(if (i32.lt_u ($COUNT $ast) 4)
|
|
|
|
(then
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $res ($INC_REF (global.get $NIL)))
|
2018-10-15 00:44:08 +03:00
|
|
|
(br $EVAL_return))
|
|
|
|
(else
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $ast ($MAL_GET_A3 $ast)))))
|
2018-10-15 00:44:08 +03:00
|
|
|
(else
|
|
|
|
($RELEASE $res)
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $ast ($MAL_GET_A2 $ast))))))
|
2018-10-15 00:44:08 +03:00
|
|
|
(br $TCO_loop))
|
|
|
|
(else (if (i32.eqz ($strcmp "fn*" $a0sym))
|
|
|
|
(then
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $a1 ($MAL_GET_A1 $ast))
|
|
|
|
(local.set $a2 ($MAL_GET_A2 $ast))
|
|
|
|
(local.set $res ($MALFUNC $a2 $a1 $env))
|
2018-10-15 00:44:08 +03:00
|
|
|
(br $EVAL_return))
|
|
|
|
(else
|
|
|
|
;; EVAL_INVOKE
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $res ($EVAL_AST $ast $env 0))
|
|
|
|
(local.set $f_args $res)
|
2018-10-15 00:44:08 +03:00
|
|
|
|
|
|
|
;; if error, return f/args for release by caller
|
2019-01-16 09:13:51 +03:00
|
|
|
(if (global.get $error_type)
|
2018-10-15 00:44:08 +03:00
|
|
|
(then
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $res $f_args)
|
2018-10-15 00:44:08 +03:00
|
|
|
(br $EVAL_return)))
|
|
|
|
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $args ($MEM_VAL0_ptr $f_args)) ;; rest
|
|
|
|
(local.set $f ($MEM_VAL1_ptr $f_args)) ;; value
|
2018-10-15 00:44:08 +03:00
|
|
|
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $ftype ($TYPE $f))
|
|
|
|
(if (i32.eq $ftype (global.get $FUNCTION_T))
|
2018-10-15 00:44:08 +03:00
|
|
|
(then
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $res (call_indirect (type $fnT) $args ($VAL0 $f)))
|
2018-10-15 00:44:08 +03:00
|
|
|
;; release f/args
|
|
|
|
($RELEASE $f_args)
|
|
|
|
(br $EVAL_return))
|
2019-01-16 09:13:51 +03:00
|
|
|
(else (if (i32.eq $ftype (global.get $MALFUNC_T))
|
2018-10-15 00:44:08 +03:00
|
|
|
(then
|
|
|
|
;; save the current environment for release
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $prev_env $env)
|
2018-10-15 00:44:08 +03:00
|
|
|
;; create new environment using env and params stored in function
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $env ($ENV_NEW_BINDS ($MEM_VAL2_ptr $f)
|
2018-10-15 00:44:08 +03:00
|
|
|
($MEM_VAL1_ptr $f) $args))
|
|
|
|
|
|
|
|
;; release previous environment if not the current EVAL env
|
|
|
|
;; because our new env refers to it and we no longer need to
|
|
|
|
;; track it (since we are TCO recurring)
|
|
|
|
(if (i32.ne $prev_env $orig_env)
|
|
|
|
(then
|
|
|
|
($RELEASE $prev_env)
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $prev_env 0)))
|
2018-10-15 00:44:08 +03:00
|
|
|
|
|
|
|
;; claim the AST before releasing the list containing it
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $ast ($MEM_VAL0_ptr $f))
|
2018-10-15 00:44:08 +03:00
|
|
|
(drop ($INC_REF $ast))
|
|
|
|
|
|
|
|
;; if we have already been here via TCO, release previous
|
|
|
|
;; ast
|
|
|
|
;; PEND_A_LV
|
|
|
|
(if $prev_ast ($RELEASE $prev_ast))
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $prev_ast $ast)
|
2018-10-15 00:44:08 +03:00
|
|
|
|
|
|
|
;; release f/args
|
|
|
|
($RELEASE $f_args)
|
|
|
|
|
|
|
|
(br $TCO_loop))
|
|
|
|
(else
|
|
|
|
($THROW_STR_1 "apply of non-function type: %d\n" $ftype)
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $res 0)
|
2018-10-15 00:44:08 +03:00
|
|
|
($RELEASE $f_args)
|
|
|
|
(br $EVAL_return)))))))))))))))
|
|
|
|
|
|
|
|
) ;; end of TCO_loop
|
|
|
|
) ;; end of EVAL_return
|
|
|
|
|
|
|
|
;; EVAL_RETURN
|
|
|
|
(if (i32.ne $env $orig_env) ($RELEASE $env))
|
|
|
|
(if $prev_ast ($RELEASE $prev_ast))
|
|
|
|
|
|
|
|
$res
|
|
|
|
)
|
|
|
|
|
|
|
|
;; PRINT
|
|
|
|
(func $PRINT (param $ast i32) (result i32)
|
|
|
|
($pr_str $ast 1)
|
|
|
|
)
|
|
|
|
|
|
|
|
;; REPL
|
|
|
|
(func $RE (param $line i32 $env i32) (result i32)
|
2018-11-12 02:55:38 +03:00
|
|
|
(LET $mv1 0 $res 0)
|
|
|
|
(block $done
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $mv1 ($READ $line))
|
|
|
|
(br_if $done (global.get $error_type))
|
2018-10-15 00:44:08 +03:00
|
|
|
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $res ($EVAL $mv1 $env))
|
2018-10-15 00:44:08 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
;; release memory from MAL_READ
|
|
|
|
($RELEASE $mv1)
|
|
|
|
$res
|
|
|
|
)
|
|
|
|
|
|
|
|
(func $REP (param $line i32 $env i32) (result i32)
|
2018-11-12 02:55:38 +03:00
|
|
|
(LET $mv2 0 $ms 0)
|
|
|
|
(block $done
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $mv2 ($RE $line $env))
|
|
|
|
(br_if $done (global.get $error_type))
|
2018-10-15 00:44:08 +03:00
|
|
|
|
|
|
|
;; ($PR_MEMORY -1 -1)
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $ms ($PRINT $mv2))
|
2018-10-15 00:44:08 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
;; release memory from RE
|
|
|
|
($RELEASE $mv2)
|
|
|
|
$ms
|
|
|
|
)
|
|
|
|
|
2019-04-15 08:57:59 +03:00
|
|
|
(func $main (param $argc i32 $argv i32) (result i32)
|
2018-11-12 02:55:38 +03:00
|
|
|
(LET $line (STATIC_ARRAY 201)
|
Test uncaught throw, catchless try* . Fix 46 impls.
Fixes made to: ada, c, chuck, clojure, coffee, common-lisp, cpp,
crystal, d, dart, elm, erlang, es6, factor, fsharp, gnu-smalltalk,
groovy, guile, haxe, hy, js, livescript, matlab, miniMAL, nasm, nim,
objc, objpascal, ocaml, perl, perl6, php, plsql, ps, python, r,
rpython, ruby, scheme, swift3, tcl, ts, vb, vimscript, wasm, yorick.
Catchless try* test is an optional test. Not all implementations
support catchless try* but a number were fixed so they at least don't
crash on catchless try*.
2018-12-03 22:20:44 +03:00
|
|
|
$res 0 $repl_env 0 $ms 0)
|
2018-10-15 00:44:08 +03:00
|
|
|
|
|
|
|
;; DEBUG
|
2019-01-16 09:13:51 +03:00
|
|
|
;; ($printf_1 "memoryBase: 0x%x\n" (global.get $memoryBase))
|
|
|
|
;; ($printf_1 "heap_start: 0x%x\n" (global.get $heap_start))
|
|
|
|
;; ($printf_1 "heap_end: 0x%x\n" (global.get $heap_end))
|
|
|
|
;; ($printf_1 "mem: 0x%x\n" (global.get $mem))
|
|
|
|
;; ($printf_1 "string_mem: %d\n" (global.get $string_mem))
|
2018-10-15 00:44:08 +03:00
|
|
|
|
2019-01-16 09:13:51 +03:00
|
|
|
(global.set $repl_env ($ENV_NEW (global.get $NIL)))
|
|
|
|
(local.set $repl_env (global.get $repl_env))
|
2018-10-15 00:44:08 +03:00
|
|
|
|
|
|
|
;; core.EXT: defined in wasm
|
|
|
|
($add_core_ns $repl_env)
|
|
|
|
|
2018-11-12 00:30:42 +03:00
|
|
|
($checkpoint_user_memory)
|
|
|
|
|
2018-10-15 00:44:08 +03:00
|
|
|
;; core.mal: defined using the language itself
|
|
|
|
($RELEASE ($RE "(def! not (fn* (a) (if a false true)))" $repl_env))
|
|
|
|
|
|
|
|
;;($PR_MEMORY -1 -1)
|
|
|
|
|
|
|
|
;; Start REPL
|
|
|
|
(block $repl_done
|
|
|
|
(loop $repl_loop
|
2018-11-12 00:30:42 +03:00
|
|
|
(br_if $repl_done (i32.eqz ($readline "user> " $line)))
|
|
|
|
(br_if $repl_loop (i32.eq (i32.load8_u $line) 0))
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $res ($REP $line $repl_env))
|
|
|
|
(if (global.get $error_type)
|
2018-10-15 00:44:08 +03:00
|
|
|
(then
|
2019-01-16 09:13:51 +03:00
|
|
|
(if (i32.eq 2 (global.get $error_type))
|
Test uncaught throw, catchless try* . Fix 46 impls.
Fixes made to: ada, c, chuck, clojure, coffee, common-lisp, cpp,
crystal, d, dart, elm, erlang, es6, factor, fsharp, gnu-smalltalk,
groovy, guile, haxe, hy, js, livescript, matlab, miniMAL, nasm, nim,
objc, objpascal, ocaml, perl, perl6, php, plsql, ps, python, r,
rpython, ruby, scheme, swift3, tcl, ts, vb, vimscript, wasm, yorick.
Catchless try* test is an optional test. Not all implementations
support catchless try* but a number were fixed so they at least don't
crash on catchless try*.
2018-12-03 22:20:44 +03:00
|
|
|
(then
|
2019-01-16 09:13:51 +03:00
|
|
|
(local.set $ms ($pr_str (global.get $error_val) 1))
|
Test uncaught throw, catchless try* . Fix 46 impls.
Fixes made to: ada, c, chuck, clojure, coffee, common-lisp, cpp,
crystal, d, dart, elm, erlang, es6, factor, fsharp, gnu-smalltalk,
groovy, guile, haxe, hy, js, livescript, matlab, miniMAL, nasm, nim,
objc, objpascal, ocaml, perl, perl6, php, plsql, ps, python, r,
rpython, ruby, scheme, swift3, tcl, ts, vb, vimscript, wasm, yorick.
Catchless try* test is an optional test. Not all implementations
support catchless try* but a number were fixed so they at least don't
crash on catchless try*.
2018-12-03 22:20:44 +03:00
|
|
|
($printf_1 "Error: %s\n" ($to_String $ms))
|
|
|
|
($RELEASE $ms)
|
2019-01-16 09:13:51 +03:00
|
|
|
($RELEASE (global.get $error_val)))
|
Test uncaught throw, catchless try* . Fix 46 impls.
Fixes made to: ada, c, chuck, clojure, coffee, common-lisp, cpp,
crystal, d, dart, elm, erlang, es6, factor, fsharp, gnu-smalltalk,
groovy, guile, haxe, hy, js, livescript, matlab, miniMAL, nasm, nim,
objc, objpascal, ocaml, perl, perl6, php, plsql, ps, python, r,
rpython, ruby, scheme, swift3, tcl, ts, vb, vimscript, wasm, yorick.
Catchless try* test is an optional test. Not all implementations
support catchless try* but a number were fixed so they at least don't
crash on catchless try*.
2018-12-03 22:20:44 +03:00
|
|
|
(else
|
2019-01-16 09:13:51 +03:00
|
|
|
($printf_1 "Error: %s\n" (global.get $error_str))))
|
|
|
|
(global.set $error_type 0))
|
2018-10-15 00:44:08 +03:00
|
|
|
(else
|
|
|
|
($printf_1 "%s\n" ($to_String $res))))
|
|
|
|
($RELEASE $res)
|
2018-11-12 00:30:42 +03:00
|
|
|
;;($PR_MEMORY_SUMMARY_SMALL)
|
|
|
|
(br $repl_loop)
|
|
|
|
)
|
|
|
|
)
|
2018-10-15 00:44:08 +03:00
|
|
|
|
|
|
|
($print "\n")
|
|
|
|
;;($PR_MEMORY -1 -1)
|
|
|
|
0
|
|
|
|
)
|
|
|
|
|
|
|
|
)
|
|
|
|
|