From d4af7352072e0bff9d803f2ad9fa45b3e48609a3 Mon Sep 17 00:00:00 2001 From: mtardy Date: Wed, 2 Sep 2020 09:04:22 +0200 Subject: [PATCH 1/2] Add TYPESIG and CASE macros to switch between types combinations more elegantly --- object.c | 4 ++++ parse.leg | 37 +++++++++++++++++++++---------------- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/object.c b/object.c index 66a97d8..ad4c1d5 100644 --- a/object.c +++ b/object.c @@ -77,6 +77,10 @@ typedef enum { Map } type_t; +#define NTYPES (Map + 1) +#define TYPESIG(L, R) L*NTYPES+R +#define CASE(L, R) case TYPESIG(L, R) + union object; typedef union object *oop; diff --git a/parse.leg b/parse.leg index 018850b..c4f7061 100644 --- a/parse.leg +++ b/parse.leg @@ -991,28 +991,33 @@ void runtimeError(char *msg) oop addOperation(oop ast, oop lhs, oop rhs) { - if (getType(lhs) == Integer && getType(rhs) == Integer) { - return makeInteger(getInteger(lhs) + getInteger(rhs)); - } else if (getType(lhs) == String && getType(rhs) == String) { - return string_concat(lhs, rhs); - } else { - runtimeError("addition between two incompatible types"); - assert(0); // to prevent: control may reach end of non-void function + switch (TYPESIG(getType(lhs), getType(rhs))) { + CASE(Integer, Integer): { + return makeInteger(getInteger(lhs) + getInteger(rhs)); + } + CASE(String, String): { + return string_concat(lhs, rhs); + } } + runtimeError("addition between two incompatible types"); + assert(0); // to prevent: control may reach end of non-void function } oop mulOperation(oop ast, oop lhs, oop rhs) { - if (getType(lhs) == Integer && getType(rhs) == Integer) { - return makeInteger(getInteger(lhs) * getInteger(rhs)); - } else if (getType(lhs) == String && getType(rhs) == Integer) { - return string_mul(lhs, rhs); - } else if (getType(lhs) == Integer && getType(rhs) == String) { - return string_mul(rhs, lhs); - } else { - runtimeError("multiplication between two incompatible types"); - assert(0); + switch (TYPESIG(getType(lhs), getType(rhs))) { + CASE(Integer, Integer): { + return makeInteger(getInteger(lhs) * getInteger(rhs)); + } + CASE(String, Integer): { + return string_mul(lhs, rhs); + } + CASE(Integer, String): { + return string_mul(rhs, lhs); + } } + runtimeError("multiplication between two incompatible types"); + assert(0); } oop expandUnquotes(oop scope, oop obj) From 530e71426be4470faf2a6a5ca42028fdcb8568a2 Mon Sep 17 00:00:00 2001 From: mtardy Date: Wed, 2 Sep 2020 11:06:13 +0200 Subject: [PATCH 2/2] Move TYPESIG and CASE macros and undef them --- object.c | 2 -- parse.leg | 6 ++++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/object.c b/object.c index ad4c1d5..85e3dff 100644 --- a/object.c +++ b/object.c @@ -78,8 +78,6 @@ typedef enum { } type_t; #define NTYPES (Map + 1) -#define TYPESIG(L, R) L*NTYPES+R -#define CASE(L, R) case TYPESIG(L, R) union object; typedef union object *oop; diff --git a/parse.leg b/parse.leg index c4f7061..78b0412 100644 --- a/parse.leg +++ b/parse.leg @@ -989,6 +989,9 @@ void runtimeError(char *msg) exit(1); } +#define TYPESIG(L, R) L*NTYPES+R +#define CASE(L, R) case TYPESIG(L, R) + oop addOperation(oop ast, oop lhs, oop rhs) { switch (TYPESIG(getType(lhs), getType(rhs))) { @@ -1020,6 +1023,9 @@ oop mulOperation(oop ast, oop lhs, oop rhs) assert(0); } +#undef TYPESIG +#undef CASE + oop expandUnquotes(oop scope, oop obj) { obj = clone(obj);