From f4adaed45668608cadbe1467304e3e1a32145bfc Mon Sep 17 00:00:00 2001 From: Alexandre Bique Date: Wed, 4 Mar 2009 00:23:53 +0000 Subject: [PATCH] using my new generic multi-method --- src/ast/CMakeLists.txt | 1 + src/ast/cast-tables.cc | 103 +++++++++++++++++++++++++ src/ast/cast-tables.hh | 12 +++ src/ast/simplify-visitor.cc | 4 +- src/ast/type-checker-visitor.cc | 165 +++++++++------------------------------- src/ast/type-checker-visitor.hh | 20 ----- src/core/multi-method.hh | 8 +- 7 files changed, 157 insertions(+), 156 deletions(-) create mode 100644 src/ast/cast-tables.cc create mode 100644 src/ast/cast-tables.hh diff --git a/src/ast/CMakeLists.txt b/src/ast/CMakeLists.txt index de375a2..794fe88 100644 --- a/src/ast/CMakeLists.txt +++ b/src/ast/CMakeLists.txt @@ -29,6 +29,7 @@ ADD_LIBRARY(ast ast.cc ascii-visitor.cc browse-visitor.cc + cast-tables.cc default-visitor.cc llvm-generator-visitor.cc type-checker-visitor.cc diff --git a/src/ast/cast-tables.cc b/src/ast/cast-tables.cc new file mode 100644 index 0000000..d67855d --- /dev/null +++ b/src/ast/cast-tables.cc @@ -0,0 +1,103 @@ +#include +#include "cast-tables.hh" + +namespace ast +{ + typedef + core::DispatchTable castTable_t; + namespace best_type + { + static castTable_t * table = 0; + + static + core::DispatchTable * integerTypeTable = 0; + +#define DUMMY_CAST(Type1, Type2) \ + CastExp * \ + cast##Type1##Type2(Type * /*type1*/, \ + Type * /*type2*/) \ + { \ + return 0; \ + } + + DUMMY_CAST(Bool, Bool) + DUMMY_CAST(Float, Float) + DUMMY_CAST(Double, Double) + +#define TRIVIAL_CAST(Type1, Type2) \ + CastExp * \ + cast##Type1##Type2(Type * type1, \ + Type * type2) \ + { \ + CastExp * castExp = new CastExp(); \ + \ + if (type1->nodeType == Type2##Type::nodeTypeId()) \ + castExp->type = type1; \ + else \ + castExp->type = type2; \ + return castExp; \ + } + + TRIVIAL_CAST(Bool, Integer) + TRIVIAL_CAST(Bool, Float) + TRIVIAL_CAST(Bool, Double) + TRIVIAL_CAST(Integer, Float) + TRIVIAL_CAST(Integer, Double) + TRIVIAL_CAST(Float, Double) + + CastExp * + castIntegerInteger(Type * type1, + Type * type2) + { + CastExp * castExp = 0; + IntegerType * itype1 = reinterpret_cast (type1); + IntegerType * itype2 = reinterpret_cast (type2); + + if (itype1->size == itype2->size && itype1->isSigned == itype2->isSigned) + return 0; + castExp = new CastExp(); + if (itype1->size > itype2->size) + castExp->type = itype1; + else + castExp->type = itype2; + return castExp; + } + + void + init() + { + table = new castTable_t(); + +#define ADD_ENTRY(Type1, Type2) \ + table->addEntry(cast##Type1##Type2, \ + Type1##Type::nodeTypeId(), \ + Type2##Type::nodeTypeId()); \ + table->addEntry(cast##Type1##Type2, \ + Type2##Type::nodeTypeId(), \ + Type1##Type::nodeTypeId()); + + ADD_ENTRY(Bool, Bool); + ADD_ENTRY(Bool, Integer); + ADD_ENTRY(Bool, Float); + ADD_ENTRY(Bool, Double); + ADD_ENTRY(Integer, Integer); + ADD_ENTRY(Integer, Float); + ADD_ENTRY(Integer, Double); + ADD_ENTRY(Float, Float); + ADD_ENTRY(Float, Double); + ADD_ENTRY(Double, Double); + } + } + + CastExp * + castToBestType(Type * type1, Type * type2) + { + if (!best_type::table) + best_type::init(); + assert(type1); + assert(type2); + return best_type::table->dispatch(type1->nodeType, type2->nodeType)(type1, type2); + } +} diff --git a/src/ast/cast-tables.hh b/src/ast/cast-tables.hh new file mode 100644 index 0000000..72440e1 --- /dev/null +++ b/src/ast/cast-tables.hh @@ -0,0 +1,12 @@ +#ifndef AST_CAST_TABLES_HH +# define AST_CAST_TABLES_HH + +# include + +namespace ast +{ + CastExp * castToBestType(Type * type1, Type * type2); + CastExp * castToIntegerType(Type * type1, Type * type2); +} + +#endif /* !CAST_TABLES_HH */ diff --git a/src/ast/simplify-visitor.cc b/src/ast/simplify-visitor.cc index b942b2b..2ec0e24 100644 --- a/src/ast/simplify-visitor.cc +++ b/src/ast/simplify-visitor.cc @@ -2,8 +2,8 @@ #include #include +#include #include "simplify-visitor.hh" -#include "type-checker-visitor.hh" namespace ast { @@ -168,7 +168,7 @@ namespace ast node.exp->accept(*this); node.exp = replacement_; - if (!TypeCheckerVisitor::findCast(node.type, node.exp->type)) + if (!castToBestType(node.type, node.exp->type)) return; AssignExp * assign = new AssignExp(); diff --git a/src/ast/type-checker-visitor.cc b/src/ast/type-checker-visitor.cc index 50f95f6..f0344b5 100644 --- a/src/ast/type-checker-visitor.cc +++ b/src/ast/type-checker-visitor.cc @@ -2,44 +2,16 @@ #include +#include +#include #include "type-checker-visitor.hh" -#include "scope.hh" namespace ast { - TypeCheckerVisitor::castTable_t TypeCheckerVisitor::castTable_; - TypeCheckerVisitor::TypeCheckerVisitor() : BrowseVisitor(), scope_() { -#define ADD_CAST_TABLE_ENTRY(Type1, Type2, Method) \ - do { \ - const id_t id1 = Type1::nodeTypeId(); \ - const id_t id2 = Type2::nodeTypeId(); \ - castTableKey_t key; \ - if (id1 < id2) \ - key = std::make_pair(id1, id2); \ - else \ - key = std::make_pair(id2, id1); \ - assert_msg(!castTable_.count(key), \ - "the same key has been insterted two times"); \ - castTable_[key] = TypeCheckerVisitor::Method; \ - } while (0) - - if (castTable_.empty()) - { - ADD_CAST_TABLE_ENTRY(BoolType, BoolType, castBoolBool); - ADD_CAST_TABLE_ENTRY(BoolType, IntegerType, castBoolInteger); - ADD_CAST_TABLE_ENTRY(BoolType, FloatType, castBoolFloat); - ADD_CAST_TABLE_ENTRY(BoolType, DoubleType, castBoolDouble); - ADD_CAST_TABLE_ENTRY(IntegerType, IntegerType, castIntegerInteger); - ADD_CAST_TABLE_ENTRY(IntegerType, FloatType, castIntegerFloat); - ADD_CAST_TABLE_ENTRY(IntegerType, DoubleType, castIntegerDouble); - ADD_CAST_TABLE_ENTRY(FloatType, FloatType, castFloatFloat); - ADD_CAST_TABLE_ENTRY(FloatType, DoubleType, castFloatDouble); - ADD_CAST_TABLE_ENTRY(DoubleType, DoubleType, castDoubleDouble); - } } TypeCheckerVisitor::~TypeCheckerVisitor() @@ -103,36 +75,37 @@ namespace ast node.exp->accept(*this); } -#define VISIT(Type) \ - void \ - TypeCheckerVisitor::visit(Type & node) \ - { \ - node.left->accept(*this); \ - node.right->accept(*this); \ - /** \ - * @todo check if type match \ - * @todo look for an overloaded operator '+' \ - * @todo the cast can be applied on both nodes \ - */ \ - CastExp * castExp = findCast(node.left->type, node.right->type); \ - \ - if (!castExp) \ - { \ - node.type = node.left->type; \ - return; \ - } \ - \ - if (castExp->type == node.left->type) \ - { \ - castExp->exp = node.right; \ - node.right = castExp; \ - } \ - else \ - { \ - castExp->exp = node.left; \ - node.left = castExp; \ - } \ - node.type = castExp->type; \ +#define VISIT(Type) \ + void \ + TypeCheckerVisitor::visit(Type & node) \ + { \ + node.left->accept(*this); \ + node.right->accept(*this); \ + /** \ + * @todo check if type match \ + * @todo look for an overloaded operator '+' \ + * @todo the cast can be applied on both nodes \ + */ \ + CastExp * castExp = castToBestType(node.left->type, \ + node.right->type); \ + \ + if (!castExp) \ + { \ + node.type = node.left->type; \ + return; \ + } \ + \ + if (castExp->type == node.left->type) \ + { \ + castExp->exp = node.right; \ + node.right = castExp; \ + } \ + else \ + { \ + castExp->exp = node.left; \ + node.left = castExp; \ + } \ + node.type = castExp->type; \ } VISIT(AddExp) @@ -159,7 +132,8 @@ namespace ast node.left->accept(*this); \ node.right->accept(*this); \ \ - CastExp * castExp = findCast(node.left->type, node.right->type); \ + CastExp * castExp = castToBestType(node.left->type, \ + node.right->type); \ \ if (!castExp) \ { \ @@ -213,73 +187,4 @@ namespace ast VISIT_BINARY_BOOL_EXP(OrOrExp) VISIT_BINARY_BOOL_EXP(AndAndExp) - - CastExp * - TypeCheckerVisitor::findCast(Type * type1, - Type * type2) - { - assert(type1); - assert(type2); - - castTableKey_t key; - if (type1->nodeType < type2->nodeType) - key = std::make_pair(type1->nodeType, type2->nodeType); - else - key = std::make_pair(type2->nodeType, type1->nodeType); - assert(castTable_.count(key) > 0); - - CastExp * castExp = castTable_[key](type1, type2); - return castExp; - } - -#define DUMMY_CAST(Type1, Type2) \ - CastExp * \ - TypeCheckerVisitor::cast##Type1##Type2(Type * /*type1*/, \ - Type * /*type2*/) \ - { \ - return 0; \ - } - - DUMMY_CAST(Bool, Bool) - DUMMY_CAST(Float, Float) - DUMMY_CAST(Double, Double) - -#define TRIVIAL_CAST(Type1, Type2) \ - CastExp * \ - TypeCheckerVisitor::cast##Type1##Type2(Type * type1, \ - Type * type2) \ - { \ - CastExp * castExp = new CastExp(); \ - \ - if (type1->nodeType == Type2##Type::nodeTypeId()) \ - castExp->type = type1; \ - else \ - castExp->type = type2; \ - return castExp; \ - } - - TRIVIAL_CAST(Bool, Integer) - TRIVIAL_CAST(Bool, Float) - TRIVIAL_CAST(Bool, Double) - TRIVIAL_CAST(Integer, Float) - TRIVIAL_CAST(Integer, Double) - TRIVIAL_CAST(Float, Double) - - CastExp * - TypeCheckerVisitor::castIntegerInteger(Type * type1, - Type * type2) - { - CastExp * castExp = 0; - IntegerType * itype1 = reinterpret_cast (type1); - IntegerType * itype2 = reinterpret_cast (type2); - - if (itype1->size == itype2->size && itype1->isSigned == itype2->isSigned) - return 0; - castExp = new CastExp(); - if (itype1->size > itype2->size) - castExp->type = itype1; - else - castExp->type = itype2; - return castExp; - } } diff --git a/src/ast/type-checker-visitor.hh b/src/ast/type-checker-visitor.hh index 9f83352..956ea96 100644 --- a/src/ast/type-checker-visitor.hh +++ b/src/ast/type-checker-visitor.hh @@ -54,29 +54,9 @@ namespace ast virtual void visit(Block & node); public: - /// @todo move the cast part in an other place - typedef std::pair castTableKey_t; - typedef CastExp * (*castTableValue_t)(Type * type1, Type * type2); - typedef std::map castTable_t; typedef BrowseVisitor super_t; - static CastExp * findCast(Type * type1, Type * type2); - private: - static CastExp * castBoolBool(Type * type1, Type * type2); - static CastExp * castBoolInteger(Type * type1, Type * type2); - static CastExp * castBoolFloat(Type * type1, Type * type2); - static CastExp * castBoolDouble(Type * type1, Type * type2); - static CastExp * castIntegerInteger(Type * type1, Type * type2); - static CastExp * castIntegerFloat(Type * type1, Type * type2); - static CastExp * castIntegerDouble(Type * type1, Type * type2); - static CastExp * castFloatFloat(Type * type1, Type * type2); - static CastExp * castFloatDouble(Type * type1, Type * type2); - static CastExp * castDoubleDouble(Type * type1, Type * type2); - - - - static castTable_t castTable_; Scope * scope_; }; } diff --git a/src/core/multi-method.hh b/src/core/multi-method.hh index c3aca1b..96ebc5b 100644 --- a/src/core/multi-method.hh +++ b/src/core/multi-method.hh @@ -1,5 +1,5 @@ -#ifndef CORE_MULTIMETHOD_HH -# define CORE_MULTIMETHOD_HH +#ifndef CORE_MULTI_METHOD_HH +# define CORE_MULTI_METHOD_HH # include # include @@ -20,6 +20,6 @@ namespace core }; } -# include "multimethod.hxx" +# include "multi-method.hxx" -#endif /* !CORE_MULTIMETHOD_HH */ +#endif /* !CORE_MULTI_METHOD_HH */ -- 2.11.4.GIT