Skip to content

Commit

Permalink
fix quotenode parser
Browse files Browse the repository at this point in the history
  • Loading branch information
haldai committed Mar 15, 2021
1 parent 98d0113 commit 5cd2865
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 29 deletions.
57 changes: 37 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -316,9 +316,9 @@ a = (2.0, Symbol("I''m a quoted symbol"))
true.
% wrong usage
?- a := tuple([2.0, :'I\'m a quoted symbol']),
?- a := tuple([2.0, :'I\'m a quoted symbol will be evaluated']),
:= @show(a).
UndefVarError: I''m a quoted symbol not defined
UndefVarError: I''m a quoted symbol will be evaluated not defined
false.
?- a := array('Int64', undef, 2, 2).
Expand Down Expand Up @@ -385,29 +385,26 @@ a = -2
true.
```

__Remark__: Tuples are *always* evaluated before unification, lists are not.
When unifying `X := tuple([$a])`, the stuff in `tuple/1` will be evaluated by
Julia, so `:=/2` will try to access the value of variable `:a` or `$a` by
default:
__Remark__: Symbols in lists and tuples are *always* evaluated before
`:=/2` unification, and their behaviours are different:

``` prolog
?- a := 1.
true.
?- X := [a, $a].
X = [1, $a].
?- X := [a, :a, $a, :(:a), $($a)].
X = [1, 1, $1, $1, $ ($1)].
?- X := tuple([a, :a]).
X = tuple([1, 1]).
%% behaviour of tuple is different to list
?- X := tuple([a, :a, $a, :(:a), $($a)]).
X = tuple([1, 1, 1, 1, $1]).
?- X := tuple([1+1, :a]).
X = tuple([2, 1]).
%% nothing will change under =/2 unification
?- X = [a, :a, $a, :(:a), $($a)].
X = [a, :a, $a, : (:a), $ ($a)].
?- X := tuple([1+1, $a]).
X = tuple([2, 1]).
?- X := tuple([1+1, $($a)]).
X = tuple([2, $a]).
?- X = tuple([a, :a, $a, :(:a), $($a)]).
X = tuple([a, :a, $a, : (:a), $ ($a)]).
```

Keyword assignments in a function call are represented by the `kw/2` predicate:
Expand Down Expand Up @@ -487,9 +484,23 @@ evaluate symbols in the expressions, directly assigning an atom with `Expr` will
cause errors:

``` prolog
?- jl_isdefined(a).
false.
?- e := jl_expr(:call, [+, 1, :a]).
UndefVarError: a not defined
false.
%% if a is defined
?- a := 2,
e := jl_expr(:call, [+, 1, :a]).
true.
%% instead of assigning a Expr, it assigns the evaluated results
?- := @show(e).
e = 3
true.
```

To assign a variable with value of Julia `Expr` via `:=/2`, please use the
Expand All @@ -499,9 +510,15 @@ To assign a variable with value of Julia `Expr` via `:=/2`, please use the
?- e := $jl_expr(:call, [+, 1, :a]).
true.
%% explicitly claim "+" is a symbol with :/1
?- e := $jl_expr(:call, [:(+), 1, :a]).
true.
?- := 'Meta'.show_sexpr(e),
nl.
(:call, :+, 1, :a)
true.
%% evaluate the expression e (will fail because a is not defined)
?- := @show(eval(e)).
UndefVarError: a not defined
Expand Down Expand Up @@ -568,12 +585,12 @@ A = [: (+), 1, :b].
%% unify with nested expressions
?- X1 = jl_expr(:call, [:(+), :a, 2]),
e $= jl_expr(:call, [:(*), X1, :a]).
e $= jl_expr(:call, [:(*), X1, :a]).
X1 = jl_expr(:call, [: (+), :a, 2]).
?- X := e, writeln(X).
jl_expr(:call,[: (*),jl_expr(:call,[: (+),jl_expr(:call,[: (+),1,:b]),2]),jl_expr(:call,[: (+),1,:b])])
X = jl_expr(:call, [: (*), jl_expr(:call, [: (+), jl_expr(:call, [: (+), 1|...]), 2]), jl_expr(:call, [: (+), 1, :b])]).
jl_expr(:call,[: (*),jl_expr(:call,[: (+),:a,2]),:a])
X = jl_expr(:call, [: (*), jl_expr(:call, [: (+), :a, 2]), :a]).
```

## TODO: Multi-dimension Arrays
Expand Down
28 changes: 19 additions & 9 deletions c/jurassic.c
Original file line number Diff line number Diff line change
Expand Up @@ -582,8 +582,17 @@ jl_expr_t *compound_to_jl_expr(term_t expr) {
printf(" Command string: %s.\n", cmd_str);
#endif
return (jl_expr_t *) checked_send_command_str(cmd_str);
} else if (fname[0] == ':' && arity < 2) {
return (jl_expr_t *) pl2sym(expr);
} else if (PL_is_functor(expr, FUNCTOR_quote1) && arity < 2) {
term_t expr_arg = PL_new_term_ref();
if (!PL_get_arg(1, expr, expr_arg)) {
printf("[ERR] Reading quoted symbol failed!\n");
return NULL;
}
if (PL_is_compound(expr_arg)) {
// QuoteNode?
return (jl_expr_t *) jl_new_struct(jl_quotenode_type, compound_to_jl_expr(expr_arg));
} else if (PL_is_atom(expr_arg))
return (jl_expr_t *) pl2sym(expr);
} else if (PL_is_functor(expr, FUNCTOR_quotenode1) && arity < 2) {
// fetch the argument
term_t arg_term = PL_new_term_ref();
Expand Down Expand Up @@ -1239,16 +1248,17 @@ int jl_unify_pl(jl_value_t *val, term_t *ret) {
return PL_unify_string_chars(tmp_term, retval);
} else if (jl_is_quotenode(val)) {
#ifdef JURASSIC_DEBUG
printf(" QuoteNode: ");
printf(" QuoteNode of ");
#endif
const char *retval = jl_symbol_name((jl_sym_t *) jl_quotenode_value(val));
jl_value_t *quotedval = jl_quotenode_value(val);
#ifdef JURASSIC_DEBUG
printf(":%s.\n", retval);
jl_static_show(JL_STDOUT, (jl_value_t *) quotedval);
printf(".\n");
#endif
term_t qname = PL_new_term_ref();
return PL_put_atom(qname, PL_new_atom(retval)) &&
PL_unify_functor(tmp_term, FUNCTOR_quotenode1) &&
PL_unify_arg(1, tmp_term, qname);
term_t qval = PL_new_term_ref();
return jl_unify_pl(quotedval, &qval)
&& PL_unify_functor(tmp_term, FUNCTOR_quotenode1)
&& PL_unify_arg(1, tmp_term, qval);
} else if (jl_is_symbol(val)) {
#ifdef JURASSIC_DEBUG
printf(" Symbol (Atom): ");
Expand Down

0 comments on commit 5cd2865

Please sign in to comment.