From cbc132e58b9bc4f14dada78e67564a8449f5ee44 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Astor?= Date: Sat, 12 Sep 2020 13:36:27 +0200 Subject: [PATCH] :art: Add pre and post -fix functions --- ast | 2 +- src/parse/scan1.c | 39 ++++++++++++++++++++++++++++++++++++++ tests/xxxfix/bin_func.gw | 5 +++++ tests/xxxfix/post_func.gw | 5 +++++ tests/xxxfix/unary_func.gw | 5 +++++ 5 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 tests/xxxfix/bin_func.gw create mode 100644 tests/xxxfix/post_func.gw create mode 100644 tests/xxxfix/unary_func.gw diff --git a/ast b/ast index c83cc91c..54b9c959 160000 --- a/ast +++ b/ast @@ -1 +1 @@ -Subproject commit c83cc91cd55f2ee3036bfe5a04fc06cd191b6ded +Subproject commit 54b9c95972359ad1e835c9d1d47243e31e09da8c diff --git a/src/parse/scan1.c b/src/parse/scan1.c index ea01e2cf..9f2c0056 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -1,3 +1,4 @@ +#include #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 index 00000000..8b0fcf63 --- /dev/null +++ b/tests/xxxfix/bin_func.gw @@ -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 index 00000000..eb7b75de --- /dev/null +++ b/tests/xxxfix/post_func.gw @@ -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 index 00000000..20ea20f9 --- /dev/null +++ b/tests/xxxfix/unary_func.gw @@ -0,0 +1,5 @@ +fun int add(int i) { + return i + 3; +} + +<<< (@add) 2 >>>; -- 2.43.0