diff --git a/lib/c3/0.1/c3.facts b/lib/c3/0.1/c3.facts
index 10c0887..9732d2c 100644
--- a/lib/c3/0.1/c3.facts
+++ b/lib/c3/0.1/c3.facts
@@ -14,6 +14,7 @@ add {C3, :symbol, C3.<}
add {C3, :symbol, C3.==}
add {C3, :symbol, C3.>=}
add {C3, :symbol, C3.>}
+add {C3, :symbol, C3._"()"}
add {C3, :symbol, C3.break}
add {C3, :symbol, C3.first}
add {C3, :symbol, C3.||}
@@ -66,7 +67,10 @@ add {C3.!, :arity, 1}
add {C3.!, :cfn, cfn :bool "tag_not" (:tag)}
add {C3.!, :is_a, :operator}
add {C3.!, :operator_precedence, 4}
-add {C3.!, :operator_associativity, :left}
+add {C3._"()", :arity, 1}
+add {C3._"()", :cfn, cfn :tag "tag_paren" (:tag)}
+add {C3._"()", :is_a, :operator}
+add {C3._"()", :operator_precedence, 4}
add {C3.&&, :arity, 2}
add {C3.&&, :cfn, cfn :bool "tag_and" (:tag, :tag)}
add {C3.&&, :is_a, :operator}
diff --git a/libc3/buf_parse.c b/libc3/buf_parse.c
index 98e5bf5..29ee7f2 100644
--- a/libc3/buf_parse.c
+++ b/libc3/buf_parse.c
@@ -609,9 +609,6 @@ sw buf_parse_call_op_rec (s_buf *buf, s_call *dest, u8 min_precedence)
break;
if (r > 0 && c == '\n')
break;
- if ((r = buf_ignore_spaces(buf)) < 0)
- break;
- result += r;
r = buf_parse_ident_peek(buf, &next_op);
if (r <= 0)
break;
@@ -629,9 +626,15 @@ sw buf_parse_call_op_rec (s_buf *buf, s_call *dest, u8 min_precedence)
}
result += r;
tag_init_call(right, &tmp2);
- if ((r = buf_ignore_spaces(buf)) < 0)
+ if ((r = buf_ignore_spaces_but_newline(buf)) < 0)
break;
result += r;
+ if ((r = buf_peek_character_utf8(buf, &c)) <= 0)
+ break;
+ if (r > 0 && c == '\n') {
+ r = -1;
+ break;
+ }
r = buf_parse_ident_peek(buf, &next_op);
if (r > 0)
next_op_precedence = operator_precedence(&next_op);
@@ -689,6 +692,41 @@ sw buf_parse_call_op_unary (s_buf *buf, s_call *dest)
return r;
}
+sw buf_parse_call_paren (s_buf *buf, s_call *dest)
+{
+ sw r;
+ sw result = 0;
+ s_call tmp;
+ s_buf_save save;
+ call_init_op_unary(&tmp);
+ ident_init_1(&tmp.ident, "()");
+ buf_save_init(buf, &save);
+ if ((r = buf_read_1(buf, "(")) <= 0)
+ goto restore;
+ result += r;
+ if ((r = buf_ignore_spaces(buf)) < 0)
+ goto restore;
+ result += r;
+ if ((r = buf_parse_tag(buf, &tmp.arguments->tag)) <= 0)
+ goto restore;
+ result += r;
+ if ((r = buf_ignore_spaces(buf)) < 0)
+ goto restore;
+ result += r;
+ if ((r = buf_read_1(buf, ")")) <= 0)
+ goto restore;
+ result += r;
+ *dest = tmp;
+ r = result;
+ goto clean;
+ restore:
+ call_clean(&tmp);
+ buf_save_restore_rpos(buf, &save);
+ clean:
+ buf_save_clean(buf, &save);
+ return r;
+}
+
sw buf_parse_cfn (s_buf *buf, s_cfn *dest)
{
s_list *arg_types = NULL;
@@ -2069,6 +2107,16 @@ sw buf_parse_tag_call_op (s_buf *buf, s_tag *dest)
return r;
}
+sw buf_parse_tag_call_paren (s_buf *buf, s_tag *dest)
+{
+ sw r;
+ assert(buf);
+ assert(dest);
+ if ((r = buf_parse_call_paren(buf, &dest->data.call)) > 0)
+ dest->type = TAG_CALL;
+ return r;
+}
+
sw buf_parse_tag_call_op_unary (s_buf *buf, s_tag *dest)
{
sw r;
@@ -2155,7 +2203,8 @@ sw buf_parse_tag_primary (s_buf *buf, s_tag *dest)
goto restore;
result += r;
}
- if ((r = buf_parse_tag_call_op_unary(buf, dest)) != 0 ||
+ if ((r = buf_parse_tag_call_paren(buf, dest)) != 0 ||
+ (r = buf_parse_tag_call_op_unary(buf, dest)) != 0 ||
(r = buf_parse_tag_bool(buf, dest)) != 0 ||
(r = buf_parse_tag_character(buf, dest)) != 0)
goto end;
diff --git a/libc3/buf_parse.h b/libc3/buf_parse.h
index 64a01a1..9102496 100644
--- a/libc3/buf_parse.h
+++ b/libc3/buf_parse.h
@@ -50,6 +50,7 @@ sw buf_parse_call_args_paren (s_buf *buf, s_call *dest);
sw buf_parse_call_op (s_buf *buf, s_call *dest);
sw buf_parse_call_op_rec (s_buf *buf, s_call *dest, u8 min_precedence);
sw buf_parse_call_op_unary (s_buf *buf, s_call *dest);
+sw buf_parse_call_paren (s_buf *buf, s_call *dest);
sw buf_parse_cfn (s_buf *buf, s_cfn *dest);
sw buf_parse_character (s_buf *buf, character *dest);
sw buf_parse_comments (s_buf *buf);
@@ -88,6 +89,7 @@ sw buf_parse_tag_array (s_buf *buf, s_tag *dest);
sw buf_parse_tag_bool (s_buf *buf, s_tag *dest);
sw buf_parse_tag_call (s_buf *buf, s_tag *dest);
sw buf_parse_tag_call_op (s_buf *buf, s_tag *dest);
+sw buf_parse_tag_call_paren (s_buf *buf, s_tag *dest);
sw buf_parse_tag_cfn (s_buf *buf, s_tag *dest);
sw buf_parse_tag_character (s_buf *buf, s_tag *dest);
sw buf_parse_tag_fn (s_buf *buf, s_tag *dest);
diff --git a/libc3/tag.c b/libc3/tag.c
index c182a47..41076ce 100644
--- a/libc3/tag.c
+++ b/libc3/tag.c
@@ -1536,6 +1536,11 @@ bool tag_or (const s_tag *a, const s_tag *b)
return compare_tag(a, &f) != 0 || compare_tag(b, &f) != 0;
}
+s_tag * tag_paren (s_tag *a)
+{
+ return a;
+}
+
s_tag * tag_s8 (s_tag *tag, s8 x)
{
assert(tag);
diff --git a/libc3/tag.h b/libc3/tag.h
index 3ab71de..49256e8 100644
--- a/libc3/tag.h
+++ b/libc3/tag.h
@@ -96,6 +96,7 @@ e_bool tag_is_bound_var (const s_tag *tag);
e_bool tag_is_number (const s_tag *tag);
e_bool tag_is_unbound_var (const s_tag *tag);
s8 tag_number_compare (const s_tag *a, const s_tag *b);
+s_tag * tag_paren (s_tag *a);
sw tag_size (const s_tag *tag);
void * tag_to_ffi_pointer (s_tag *tag, const s_sym *type);
ffi_type tag_to_ffi_type(const s_tag *tag);