]> Nishi Git Mirror - gwion.git/commitdiff
:art: Add pre and post -fix functions
authorJérémie Astor <astor.jeremie@wanadoo.fr>
Sat, 12 Sep 2020 11:36:27 +0000 (13:36 +0200)
committerJérémie Astor <astor.jeremie@wanadoo.fr>
Sat, 12 Sep 2020 11:36:27 +0000 (13:36 +0200)
ast
src/parse/scan1.c
tests/xxxfix/bin_func.gw [new file with mode: 0644]
tests/xxxfix/post_func.gw [new file with mode: 0644]
tests/xxxfix/unary_func.gw [new file with mode: 0644]

diff --git a/ast b/ast
index c83cc91cd55f2ee3036bfe5a04fc06cd191b6ded..54b9c95972359ad1e835c9d1d47243e31e09da8c 160000 (submodule)
--- a/ast
+++ b/ast
@@ -1 +1 @@
-Subproject commit c83cc91cd55f2ee3036bfe5a04fc06cd191b6ded
+Subproject commit 54b9c95972359ad1e835c9d1d47243e31e09da8c
index ea01e2cfb9313d3a3b69997adf3bccf4ea0e4b2d..9f2c0056da2f20ed92b454d669c6adb37d7f05e3 100644 (file)
@@ -1,3 +1,4 @@
+#include <ctype.h>
 #include "gwion_util.h"
 #include "gwion_ast.h"
 #include "gwion_env.h"
@@ -142,7 +143,39 @@ ANN m_bool scan1_exp_decl(const Env env, const Exp_Decl* decl) {
   return ret;
 }
 
+ANN static inline int opiscall(const Symbol sym) {
+  const m_str opname = s_name(sym);
+  return opname[0] == '@' && (isalpha(opname[1]) || opname[1] == '_');
+}
+
+ANN static inline Exp sym2func(const Env env, const Symbol sym, const loc_t pos) {
+  MemPool mp = env->gwion->mp;
+  const m_str name = s_name(sym);
+  return new_prim_id(mp, insert_symbol(name + 1), loc_cpy(mp, pos));
+}
+
+ANN static void binary_args(const Exp_Binary* bin) {
+  Exp arg = bin->lhs;
+  while(arg->next)
+    arg = arg->next;
+  arg->next = bin->rhs;
+}
+
+ANN static m_bool exp2call(const Env env, const Exp e, const Symbol sym, const Exp args) {
+  e->exp_type = ae_exp_call;
+  e->d.exp_call.func = sym2func(env, sym, e->pos);
+  e->d.exp_call.args = args;
+  return scan1_exp(env, e);
+}
+
+ANN static m_bool binary2call(const Env env, const Exp_Binary* bin) {
+  binary_args(bin);
+  return exp2call(env, exp_self(bin), bin->op, bin->lhs);
+}
+
 ANN static inline m_bool scan1_exp_binary(const Env env, const Exp_Binary* bin) {
+  if(opiscall(bin->op))
+    return binary2call(env, bin);
   CHECK_BB(scan1_exp(env, bin->lhs))
   return scan1_exp(env, bin->rhs);
 }
@@ -181,6 +214,9 @@ ANN static inline m_bool scan1_exp_cast(const Env env, const Exp_Cast* cast) {
 }
 
 ANN static m_bool scan1_exp_post(const Env env, const Exp_Postfix* post) {
+  if(opiscall(post->op)) {
+    return exp2call(env, exp_self(post), post->op, post->exp);
+  }
   CHECK_BB(scan1_exp(env, post->exp))
   const m_str access = exp_access(post->exp);
   if(!access)
@@ -213,6 +249,9 @@ ANN static m_bool scan1_exp_if(const Env env, const Exp_If* exp_if) {
 ANN static inline m_bool scan1_exp_unary(const restrict Env env, const Exp_Unary *unary) {
   if((unary->op == insert_symbol("spork") || unary->op == insert_symbol("fork")) && unary->code)
     { RET_NSPC(scan1_stmt(env, unary->code)) }
+  else if(opiscall(unary->op)) {
+    return exp2call(env, exp_self(unary), unary->op, unary->exp);
+  }
   return unary->exp ? scan1_exp(env, unary->exp) : GW_OK;
 }
 
diff --git a/tests/xxxfix/bin_func.gw b/tests/xxxfix/bin_func.gw
new file mode 100644 (file)
index 0000000..8b0fcf6
--- /dev/null
@@ -0,0 +1,5 @@
+fun int add(int i, int j) {
+  return i + j;
+}
+
+<<< 1 @add 2 >>>;
diff --git a/tests/xxxfix/post_func.gw b/tests/xxxfix/post_func.gw
new file mode 100644 (file)
index 0000000..eb7b75d
--- /dev/null
@@ -0,0 +1,5 @@
+fun int add(int i) {
+  return i + 3;
+}
+
+<<< 2 @add>>>;
diff --git a/tests/xxxfix/unary_func.gw b/tests/xxxfix/unary_func.gw
new file mode 100644 (file)
index 0000000..20ea20f
--- /dev/null
@@ -0,0 +1,5 @@
+fun int add(int i) {
+  return i + 3;
+}
+
+<<< (@add) 2 >>>;