From 4319594406fab13f5726bcd22113c8b8f9d2955a Mon Sep 17 00:00:00 2001 From: Nicolas Boulenguez Date: Sat, 5 Oct 2024 20:37:03 +0200 Subject: [PATCH] jq: backport last changes from stepA to step 3-9 --- impls/jq/step3_env.jq | 11 +++-------- impls/jq/step4_if_fn_do.jq | 16 +++++++--------- impls/jq/step5_tco.jq | 25 +++++++++++-------------- impls/jq/step6_file.jq | 17 ++++++++--------- impls/jq/step7_quote.jq | 17 ++++++++--------- impls/jq/step8_macros.jq | 22 +++++++++++----------- impls/jq/step9_try.jq | 37 ++++++++++++++++++------------------- 7 files changed, 66 insertions(+), 79 deletions(-) diff --git a/impls/jq/step3_env.jq b/impls/jq/step3_env.jq index deaf3b0d93..8e074ba441 100644 --- a/impls/jq/step3_env.jq +++ b/impls/jq/step3_env.jq @@ -61,7 +61,7 @@ def EVAL(env): select(.[0].value == "let*") | (reduce (.[1].value | nwise(2)) as $xvalue ( # Initial accumulator - {parent: env, environment:{}, fallback:null}; + {parent:env, environment:{}, fallback:null}; # Loop body . as $env | $xvalue[1] | EVAL($env) | env_set(.env; $xvalue[0].value; .expr) @@ -100,7 +100,8 @@ def EVAL(env): ) // ( select(.kind == "symbol") | - .value | env_get(env) // jqmal_error("'\(.)' not found ") | + .value | + env_get(env) // jqmal_error("'\(.)' not found") | {expr:., env:env} ) // {expr:., env:env}; @@ -108,12 +109,6 @@ def EVAL(env): def PRINT: pr_str; -def childEnv(binds; value): - { - parent: ., - environment: [binds, value] | transpose | map({(.[0]): .[1]}) | from_entries - }; - def repl: # Infinite generator, interrupted by an exception or ./run. . as $env | "user> " | __readline | diff --git a/impls/jq/step4_if_fn_do.jq b/impls/jq/step4_if_fn_do.jq index 37bb887045..a05612b902 100644 --- a/impls/jq/step4_if_fn_do.jq +++ b/impls/jq/step4_if_fn_do.jq @@ -83,7 +83,7 @@ def interpret(arguments; env; _eval): (if $DEBUG then debug("INTERP: \(. | pr_str(env))") else . end) | (select(.kind == "fn") | arg_check(arguments) | - (core_interp(arguments; env) | {expr:., env:env}) + core_interp(arguments; env) | {expr:., env:env} ) // (select(.kind == "function") as $fn | # todo: arg_check @@ -100,8 +100,8 @@ def interpret(arguments; env; _eval): . as $env | try env_set( .; $name; - $name | env_get(env) // jqmal_error("'\(.)' not found") - | . as $xvalue + $name | env_get(env) // jqmal_error("'\(.)' not found") | + . as $xvalue | if $xvalue.kind == "function" then setpath(["free_referencess"]; $fn.free_referencess) else @@ -124,7 +124,7 @@ def interpret(arguments; env; _eval): env: env } # | . as $dot - # | debug("FNPOST \(.expr | pr_str) \(; $fn.binds[0] | env_get($dot.expr.env) | pr_str)") + # | debug("FNPOST \(.expr | pr_str) \($fn.binds[0] | env_get($dot.expr.env) | pr_str)") # | debug("INTERP \($src) = \(.expr | pr_str)") ) // jqmal_error("Unsupported function kind \(.kind)"); @@ -142,16 +142,15 @@ def EVAL(env): | (select(.kind == "list") | .value | select(length != 0) as $value | - ( ( select(.[0].value == "def!") | .[1].value as $key | .[2] | EVAL(env) | - .expr as $value | if .env.replEnv != null then - addToEnv(.; $key) + addToEnv($key) else - .env |= env_set_(.; $key; $value) + .expr as $def_value | + .env |= env_set_(.; $key; $def_value) end ) // ( @@ -204,7 +203,6 @@ def EVAL(env): | $ev.expr | first | interpret($ev.expr[1:]; $ev.env; _eval_here) ) - ) ) // ( select(.kind == "vector") | diff --git a/impls/jq/step5_tco.jq b/impls/jq/step5_tco.jq index 92e9c8eee5..fdb22127c0 100644 --- a/impls/jq/step5_tco.jq +++ b/impls/jq/step5_tco.jq @@ -146,7 +146,7 @@ def EVAL(env): .env as $env | .expr | EVAL($env); . as $ast - | { env: env, ast: ., cont: true, finish: false, ret_env: null } + | TCOWrap(env; null; true) | [ recurseflip(.cont; .env as $_menv | if .finish then @@ -164,18 +164,15 @@ def EVAL(env): | (select(.kind == "list") | .value | select(length != 0) as $value | - ( ( select(.[0].value == "def!") | - ($value[2] | EVAL($_menv)) as $evval | + $value[2] | EVAL($_menv) | ( - if $evval.env.replEnv != null then - addToEnv($evval; $value[1].value) + if .env.replEnv != null then + addToEnv($value[1].value) else - { - expr: $evval.expr, - env: env_set_($evval.env; $value[1].value; $evval.expr) - } + .expr as $def_value | + .env |= env_set_(.; $value[1].value; $def_value) end ) as $val | $val.expr | TCOWrap($val.env; $_orig_retenv; false) @@ -192,10 +189,11 @@ def EVAL(env): ) // ( select(.[0].value == "do") | - (reduce ($value[1:][]) as $xvalue ( - { env: $_menv, expr: {kind:"nil"} }; - .env as $env | $xvalue | EVAL($env) - )) | . as $ex | .expr | TCOWrap($ex.env; $_orig_retenv; false) + (reduce $value[1:-1][] as $xvalue ( + $_menv; + . as $env | $xvalue | EVAL($env) | .env + )) as $env | + $value[-1] | TCOWrap($env; $_orig_retenv; true) ) // ( select(.[0].value == "if") | @@ -228,7 +226,6 @@ def EVAL(env): interpret($expr[1:]; $_menv; _eval_here) as $exprenv | $exprenv.expr | TCOWrap($exprenv.env; $_orig_retenv; false) ) - ) ) // ( select(.kind == "vector") | diff --git a/impls/jq/step6_file.jq b/impls/jq/step6_file.jq index fe5c12eae8..8d2ed95627 100644 --- a/impls/jq/step6_file.jq +++ b/impls/jq/step6_file.jq @@ -25,7 +25,7 @@ def EVAL(env): .env as $env | .expr | EVAL($env); . as $ast - | { env: env, ast: ., cont: true, finish: false, ret_env: null } + | TCOWrap(env; null; true) | [ recurseflip(.cont; .env as $_menv | if .finish then @@ -47,11 +47,10 @@ def EVAL(env): | (select(.kind == "list") | .value | select(length != 0) as $value | - ( ( select(.[0].value == "def!") | - ($value[2] | EVAL($_menv)) as $evval | - addToEnv($evval; $value[1].value) as $val | + $value[2] | EVAL($_menv) | + addToEnv($value[1].value) as $val | $val.expr | TCOWrap($val.env; $_orig_retenv; false) ) // ( @@ -67,10 +66,11 @@ def EVAL(env): ) // ( select(.[0].value == "do") | - (reduce ($value[1:][]) as $xvalue ( - { env: $_menv, expr: {kind:"nil"} }; - .env as $env | $xvalue | EVAL($env) - )) | . as $ex | .expr | TCOWrap($ex.env; $_orig_retenv; false) + (reduce $value[1:-1][] as $xvalue ( + $_menv; + . as $env | $xvalue | EVAL($env) | .env + )) as $env | + $value[-1] | TCOWrap($env; $_orig_retenv; true) ) // ( select(.[0].value == "if") | @@ -114,7 +114,6 @@ def EVAL(env): interpret($expr.val; $expr.env; _eval_here) as $exprenv | $exprenv.expr | TCOWrap($exprenv.env; $_orig_retenv; false) ) - ) ) // ( select(.kind == "vector") | diff --git a/impls/jq/step7_quote.jq b/impls/jq/step7_quote.jq index 8b0c59ec4e..5bd7b188db 100644 --- a/impls/jq/step7_quote.jq +++ b/impls/jq/step7_quote.jq @@ -60,7 +60,7 @@ def EVAL(env): .env as $env | .expr | EVAL($env); . as $ast - | { env: env, ast: ., cont: true, finish: false, ret_env: null } + | TCOWrap(env; null; true) | [ recurseflip(.cont; .env as $_menv | if .finish then @@ -82,11 +82,10 @@ def EVAL(env): | (select(.kind == "list") | .value | select(length != 0) as $value | - ( ( select(.[0].value == "def!") | - ($value[2] | EVAL($_menv)) as $evval | - addToEnv($evval; $value[1].value) as $val | + $value[2] | EVAL($_menv) | + addToEnv($value[1].value) as $val | $val.expr | TCOWrap($val.env; $_orig_retenv; false) ) // ( @@ -102,10 +101,11 @@ def EVAL(env): ) // ( select(.[0].value == "do") | - (reduce ($value[1:][]) as $xvalue ( - { env: $_menv, expr: {kind:"nil"} }; - .env as $env | $xvalue | EVAL($env) - )) | . as $ex | .expr | TCOWrap($ex.env; $_orig_retenv; false) + (reduce $value[1:-1][] as $xvalue ( + $_menv; + . as $env | $xvalue | EVAL($env) | .env + )) as $env | + $value[-1] | TCOWrap($env; $_orig_retenv; true) ) // ( select(.[0].value == "if") | @@ -157,7 +157,6 @@ def EVAL(env): interpret($expr.val; $expr.env; _eval_here) as $exprenv | $exprenv.expr | TCOWrap($exprenv.env; $_orig_retenv; false) ) - ) ) // ( select(.kind == "vector") | diff --git a/impls/jq/step8_macros.jq b/impls/jq/step8_macros.jq index 851f72ed92..f57834d34c 100644 --- a/impls/jq/step8_macros.jq +++ b/impls/jq/step8_macros.jq @@ -67,7 +67,7 @@ def EVAL(env): .env as $env | .expr | EVAL($env); . as $ast - | { env: env, ast: ., cont: true, finish: false, ret_env: null } + | TCOWrap(env; null; true) | [ recurseflip(.cont; .env as $_menv | if .finish then @@ -89,17 +89,17 @@ def EVAL(env): | (select(.kind == "list") | .value | select(length != 0) as $value | - ( ( select(.[0].value == "def!") | - ($value[2] | EVAL($_menv)) as $evval | - addToEnv($evval; $value[1].value) as $val | + $value[2] | EVAL($_menv) | + addToEnv($value[1].value) as $val | $val.expr | TCOWrap($val.env; $_orig_retenv; false) ) // ( select(.[0].value == "defmacro!") | - ($value[2] | EVAL($_menv) | (.expr |= set_macro_function)) as $evval | - addToEnv($evval; $value[1].value) as $val | + $value[2] | EVAL($_menv) | + .expr |= set_macro_function | + addToEnv($value[1].value) as $val | $val.expr | TCOWrap($val.env; $_orig_retenv; false) ) // ( @@ -115,10 +115,11 @@ def EVAL(env): ) // ( select(.[0].value == "do") | - (reduce ($value[1:][]) as $xvalue ( - { env: $_menv, expr: {kind:"nil"} }; - .env as $env | $xvalue | EVAL($env) - )) | . as $ex | .expr | TCOWrap($ex.env; $_orig_retenv; false) + (reduce $value[1:-1][] as $xvalue ( + $_menv; + . as $env | $xvalue | EVAL($env) | .env + )) as $env | + $value[-1] | TCOWrap($env; $_orig_retenv; true) ) // ( select(.[0].value == "if") | @@ -176,7 +177,6 @@ def EVAL(env): $exprenv.expr | TCOWrap($exprenv.env; $_orig_retenv; false) end ) - ) ) // ( select(.kind == "vector") | diff --git a/impls/jq/step9_try.jq b/impls/jq/step9_try.jq index 8036631f2c..d2d79543db 100644 --- a/impls/jq/step9_try.jq +++ b/impls/jq/step9_try.jq @@ -67,7 +67,7 @@ def EVAL(env): .env as $env | .expr | EVAL($env); . as $ast - | { env: env, ast: ., cont: true, finish: false, ret_env: null } + | TCOWrap(env; null; true) | [ recurseflip(.cont; .env as $_menv | if .finish then @@ -89,17 +89,17 @@ def EVAL(env): | (select(.kind == "list") | .value | select(length != 0) as $value | - ( ( select(.[0].value == "def!") | - ($value[2] | EVAL($_menv)) as $evval | - addToEnv($evval; $value[1].value) as $val | + $value[2] | EVAL($_menv) | + addToEnv($value[1].value) as $val | $val.expr | TCOWrap($val.env; $_orig_retenv; false) ) // ( select(.[0].value == "defmacro!") | - ($value[2] | EVAL($_menv) | (.expr |= set_macro_function)) as $evval | - addToEnv($evval; $value[1].value) as $val | + $value[2] | EVAL($_menv) | + .expr |= set_macro_function | + addToEnv($value[1].value) as $val | $val.expr | TCOWrap($val.env; $_orig_retenv; false) ) // ( @@ -115,18 +115,20 @@ def EVAL(env): ) // ( select(.[0].value == "do") | - (reduce ($value[1:][]) as $xvalue ( - { env: $_menv, expr: {kind:"nil"} }; - .env as $env | $xvalue | EVAL($env) - )) | . as $ex | .expr | TCOWrap($ex.env; $_orig_retenv; false) + (reduce $value[1:-1][] as $xvalue ( + $_menv; + . as $env | $xvalue | EVAL($env) | .env + )) as $env | + $value[-1] | TCOWrap($env; $_orig_retenv; true) ) // ( select(.[0].value == "try*") | + if $value[2] + and ($value[2].value[0] | .kind == "symbol" and .value == "catch*") + then try ( $value[1] | EVAL($_menv) as $exp | $exp.expr | TCOWrap($exp.env; $_orig_retenv; false) ) catch ( . as $exc | - if $value[2] then - if ($value[2].value[0] | .kind == "symbol" and .value == "catch*") then (if ($exc | is_jqmal_error) then $exc[19:] as $ex | try ( @@ -141,13 +143,11 @@ def EVAL(env): end) as $exc | $value[2].value[2] | EVAL($currentEnv | childEnv([$value[2].value[1].value]; [$exc]) | wrapEnv($replEnv; $_menv.atoms)) as $ex | $ex.expr | TCOWrap($ex.env; $_retenv; false) - else - error($exc) - end - else - error($exc) - end ) + else + $value[1] | EVAL($_menv) as $exp | + $exp.expr | TCOWrap($exp.env; $_orig_retenv; false) + end ) // ( select(.[0].value == "if") | @@ -205,7 +205,6 @@ def EVAL(env): $exprenv.expr | TCOWrap($exprenv.env; $_orig_retenv; false) end ) - ) ) // ( select(.kind == "vector") |