From 82fba464529bf6206e99ff658ec107c3461fe0be Mon Sep 17 00:00:00 2001 From: Alexandre Bique Date: Sat, 14 Mar 2009 11:54:07 +0000 Subject: [PATCH] use pointers like this: a[4] works :-) --- src/ast/CMakeLists.txt | 3 +- src/ast/cast-tables.cc | 2 ++ src/ast/llvm-generator-visitor.cc | 21 +++++++------ src/ast/llvm-generator-visitor.hh | 3 ++ src/ast/node-factory.cc | 13 ++++++-- src/ast/simplify-visitor.cc | 11 ++++--- src/ast/simplify-visitor.hh | 6 ++-- src/ast/sizeof-visitor.cc | 34 ++++++++++++++++++++ src/ast/sizeof-visitor.hh | 36 ++++++++++++++++++++++ src/ast/sizeof-visitor.hxx | 15 +++++++++ src/ast/type-checker-visitor.cc | 30 ++++++++++-------- src/ast/type-checker-visitor.hh | 4 +++ src/ast/type-checker-visitor.hxx | 8 +++++ tests/lang/mugiwara/input/pointers/index-arith.mgw | 4 +++ 14 files changed, 158 insertions(+), 32 deletions(-) create mode 100644 src/ast/sizeof-visitor.cc create mode 100644 src/ast/sizeof-visitor.hh create mode 100644 src/ast/sizeof-visitor.hxx create mode 100644 src/ast/type-checker-visitor.hxx create mode 100644 tests/lang/mugiwara/input/pointers/index-arith.mgw diff --git a/src/ast/CMakeLists.txt b/src/ast/CMakeLists.txt index 1c81c3b..c3ab3a7 100644 --- a/src/ast/CMakeLists.txt +++ b/src/ast/CMakeLists.txt @@ -34,8 +34,9 @@ ADD_LIBRARY(ast default-visitor.cc default-visitor.hh llvm-generator-visitor.cc llvm-generator-visitor.hh node-factory.cc node-factory.hh - type-checker-visitor.cc type-checker-visitor.hh + type-checker-visitor.cc type-checker-visitor.hh type-checker-visitor.hxx simplify-visitor.cc simplify-visitor.hh + sizeof-visitor.cc sizeof-visitor.hh sizeof-visitor.hxx scope.cc scope.hh scope.hxx scope-builder-visitor.cc scope-builder-visitor.hh ) diff --git a/src/ast/cast-tables.cc b/src/ast/cast-tables.cc index b85c82a..974c500 100644 --- a/src/ast/cast-tables.cc +++ b/src/ast/cast-tables.cc @@ -48,6 +48,7 @@ namespace ast TRIVIAL_CAST(Bool, Double) TRIVIAL_CAST(Integer, Float) TRIVIAL_CAST(Integer, Double) + TRIVIAL_CAST(Integer, Pointer) TRIVIAL_CAST(Float, Double) static CastExp * @@ -81,6 +82,7 @@ namespace ast ADD_SYMETRIC_ENTRY(Integer, Integer); ADD_SYMETRIC_ENTRY(Integer, Float); ADD_SYMETRIC_ENTRY(Integer, Double); + ADD_SYMETRIC_ENTRY(Integer, Pointer); ADD_SYMETRIC_ENTRY(Float, Float); ADD_SYMETRIC_ENTRY(Float, Double); ADD_SYMETRIC_ENTRY(Double, Double); diff --git a/src/ast/llvm-generator-visitor.cc b/src/ast/llvm-generator-visitor.cc index 7f59ca1..130d0d6 100644 --- a/src/ast/llvm-generator-visitor.cc +++ b/src/ast/llvm-generator-visitor.cc @@ -16,10 +16,6 @@ namespace ast assert_msg(out.good(), "The output for llvm assembly is not valid."); out_ << std::setprecision(1000); - //out_.setf(std::ios::hex, std::ios::basefield); - //out_.setf(std::ios::showbase); - - #define ADD_CAST_TABLE_ENTRY(Type1, Type2) \ do { \ castTableKey_t key = std::make_pair(Type1##Type::nodeTypeId(), \ @@ -40,6 +36,9 @@ namespace ast ADD_CAST_TABLE_ENTRY(Float, Double); ADD_CAST_TABLE_ENTRY(Float, Bool); ADD_CAST_TABLE_ENTRY(Double, Bool); + + ADD_CAST_TABLE_ENTRY(Integer, Pointer); + ADD_CAST_TABLE_ENTRY(Pointer, Integer); } LLVMGeneratorVisitor::~LLVMGeneratorVisitor() @@ -447,19 +446,23 @@ namespace ast return; } -#define SIMPLE_NUMBER_CAST(Type1, Type2, CastInstr, DestType) \ +#define SIMPLE_CAST(Type1, Type2, CastInstr) \ void \ LLVMGeneratorVisitor::cast##Type1##To##Type2(const CastExp & node) \ { \ out_ << CastInstr; \ + node.exp->type->accept(*this); \ node.exp->accept(*this); \ - out_ << DestType; \ + out_ << " to "; \ + node.type->accept(*this); \ return; \ } - SIMPLE_NUMBER_CAST(Bool, Float, "uitofp i1 ", " to float") - SIMPLE_NUMBER_CAST(Bool, Double, "uitofp i1 ", " to double") - SIMPLE_NUMBER_CAST(Float, Double, "fpext float ", " to double") + SIMPLE_CAST(Bool, Float, "uitofp") + SIMPLE_CAST(Bool, Double, "uitofp") + SIMPLE_CAST(Float, Double, "fpext") + SIMPLE_CAST(Integer, Pointer, "inttoptr") + SIMPLE_CAST(Pointer, Integer, "ptrtoint") void LLVMGeneratorVisitor::castBoolToInteger(const CastExp & node) diff --git a/src/ast/llvm-generator-visitor.hh b/src/ast/llvm-generator-visitor.hh index 35c027c..ec42661 100644 --- a/src/ast/llvm-generator-visitor.hh +++ b/src/ast/llvm-generator-visitor.hh @@ -102,6 +102,9 @@ namespace ast void castFloatToBool(const CastExp & node); void castDoubleToBool(const CastExp & node); + void castIntegerToPointer(const CastExp & node); + void castPointerToInteger(const CastExp & node); + typedef std::pair castTableKey_t; typedef void (LLVMGeneratorVisitor::*castTableValue_t)(const CastExp & node); diff --git a/src/ast/node-factory.cc b/src/ast/node-factory.cc index 5755624..5dfd5d7 100644 --- a/src/ast/node-factory.cc +++ b/src/ast/node-factory.cc @@ -1,6 +1,7 @@ #include #include +#include #include "node-factory.hh" namespace ast @@ -30,15 +31,21 @@ namespace ast { type = new IntegerType; type->isSigned = false; - type->size = 64; ///< @todo resolve the current pointer size + type->size = SizeofVisitor::pointerSize() * 8; } return type; } Exp * - NodeFactory::createSizeofValue(Type * /*type*/) + NodeFactory::createSizeofValue(Type * type) { - assert(false); + SizeofVisitor sv; + type->accept(sv); + + NumberExp * exp = new NumberExp; + exp->type = createUIntForPtr(); + exp->number = sv.size(); + return exp; } CastExp * diff --git a/src/ast/simplify-visitor.cc b/src/ast/simplify-visitor.cc index 0d517d5..c789798 100644 --- a/src/ast/simplify-visitor.cc +++ b/src/ast/simplify-visitor.cc @@ -71,6 +71,7 @@ namespace ast id->symbol = new Symbol; id->symbol->name = assign->dest->name; id->symbol->type = node.type; + id->symbol->address = new RegisterAddress; id->type = node.type; replacement_ = id; } @@ -78,6 +79,7 @@ namespace ast void SimplifyVisitor::visit(Block & block) { + scope_ = block.scope; std::vector backup = simplifications_; simplifications_.clear(); @@ -210,6 +212,7 @@ namespace ast id->symbol = new Symbol; id->symbol->name = node.symbol->name + "_" + nextId();; id->symbol->type = unreferencedType(node.type); + id->symbol->address = new RegisterAddress; id->type = id->symbol->type; replacement_ = id; @@ -270,13 +273,13 @@ namespace ast add->right = mul; /* cast uint addr to ptr */ - CastExp * cast2 = NodeFactory::createCastUIntToPtr(mul, node.exp->type); - Exp * exp = cast2; /// @todo remove this FUCK !!!!!!!!!!!! + Exp * cast2 = NodeFactory::createCastUIntToPtr(add, node.exp->type); /// @todo move this stuff to the typechecker, and just do an addition. TypeCheckerVisitor v; - exp->accept(v); - simplify(exp); + v.setScope(scope_); + cast2->accept(v); + simplify(cast2); /* the dereference step */ LoadVar * lv = new LoadVar; diff --git a/src/ast/simplify-visitor.hh b/src/ast/simplify-visitor.hh index fcb2863..85f80e4 100644 --- a/src/ast/simplify-visitor.hh +++ b/src/ast/simplify-visitor.hh @@ -87,9 +87,11 @@ namespace ast /// @brief the new list of 3 address instructions std::vector simplifications_; /// @brief the child which replace the previously visited node - Exp * replacement_; + Exp * replacement_; /// @brief the next id for register count - int nextId_; + int nextId_; + /// @brief the current scope, to retype check some generated expressions + Scope * scope_; }; } diff --git a/src/ast/sizeof-visitor.cc b/src/ast/sizeof-visitor.cc new file mode 100644 index 0000000..a5b4e16 --- /dev/null +++ b/src/ast/sizeof-visitor.cc @@ -0,0 +1,34 @@ +#include + +namespace ast +{ + SizeofVisitor::SizeofVisitor() + : super_t(), + size_(0) + { + } + + SizeofVisitor::~SizeofVisitor() + { + } + +#define CONST_SIZE_TYPE(Type_, Size) \ + void \ + SizeofVisitor::visit(const Type_##Type & /*node*/) \ + { \ + size_ += Size; \ + } + + CONST_SIZE_TYPE(Pointer, pointerSize()) + CONST_SIZE_TYPE(Reference, pointerSize()) + CONST_SIZE_TYPE(Void, 1) + CONST_SIZE_TYPE(Bool, 1) + CONST_SIZE_TYPE(Float, 4) + CONST_SIZE_TYPE(Double, 8) + + void + SizeofVisitor::visit(const IntegerType & node) + { + size_ += (node.size >> 3) + !!(node.size & 0x7); + } +} diff --git a/src/ast/sizeof-visitor.hh b/src/ast/sizeof-visitor.hh new file mode 100644 index 0000000..a73b01a --- /dev/null +++ b/src/ast/sizeof-visitor.hh @@ -0,0 +1,36 @@ +#ifndef AST_SIZEOF_VISITOR_HH +# define AST_SIZEOF_VISITOR_HH + +# include +# include + +namespace ast +{ + class SizeofVisitor : public ConstBrowseVisitor + { + public: + typedef ConstBrowseVisitor super_t; + + SizeofVisitor(); + virtual ~SizeofVisitor(); + + virtual void visit(const PointerType & node); + virtual void visit(const ReferenceType & node); + + virtual void visit(const VoidType & node); + virtual void visit(const BoolType & node); + virtual void visit(const IntegerType & node); + virtual void visit(const FloatType & node); + virtual void visit(const DoubleType & node); + + inline uint32_t size() const; + static inline uint32_t pointerSize(); + + protected: + uint32_t size_; + }; +} + +# include "sizeof-visitor.hxx" + +#endif /* !AST_SIZEOF_VISITOR_HH */ diff --git a/src/ast/sizeof-visitor.hxx b/src/ast/sizeof-visitor.hxx new file mode 100644 index 0000000..e387dcf --- /dev/null +++ b/src/ast/sizeof-visitor.hxx @@ -0,0 +1,15 @@ +namespace ast +{ + inline uint32_t + SizeofVisitor::size() const + { + return size_; + } + + inline uint32_t + SizeofVisitor::pointerSize() + { + /// @todo find a better solution + return 8; + } +} diff --git a/src/ast/type-checker-visitor.cc b/src/ast/type-checker-visitor.cc index 592ffae..b174e54 100644 --- a/src/ast/type-checker-visitor.cc +++ b/src/ast/type-checker-visitor.cc @@ -73,6 +73,10 @@ namespace ast void TypeCheckerVisitor::visit(IdExp & node) { + if (node.symbol && node.symbol->address && + node.symbol->address->nodeType == RegisterAddress::nodeTypeId()) + return; + assert(scope_); Symbol * s = scope_->findSymbol(node.symbol->name); assert(s); @@ -210,19 +214,19 @@ namespace ast VISIT_BITWISE_EXP(AShrExp) VISIT_BITWISE_EXP(LShrExp) -#define VISIT_BINARY_CMP_EXP(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 \ - */ \ - homogenizeTypes(node); \ - node.type = NodeFactory::createBoolType(); \ +#define VISIT_BINARY_CMP_EXP(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 \ + */ \ + homogenizeTypes(node); \ + node.type = NodeFactory::createBoolType(); \ } VISIT_BINARY_CMP_EXP(EqExp) diff --git a/src/ast/type-checker-visitor.hh b/src/ast/type-checker-visitor.hh index b611e1e..d3ebaa9 100644 --- a/src/ast/type-checker-visitor.hh +++ b/src/ast/type-checker-visitor.hh @@ -65,6 +65,8 @@ namespace ast virtual void visit(ConditionalBranch & node); + inline void setScope(Scope * scope); + protected: static void homogenizeTypes(BinaryExp & node); @@ -77,4 +79,6 @@ namespace ast }; } +# include "type-checker-visitor.hxx" + #endif /* !AST_TYPE_CHECKER_VISITOR_HH */ diff --git a/src/ast/type-checker-visitor.hxx b/src/ast/type-checker-visitor.hxx new file mode 100644 index 0000000..7a1bc7c --- /dev/null +++ b/src/ast/type-checker-visitor.hxx @@ -0,0 +1,8 @@ +namespace ast +{ + inline void + TypeCheckerVisitor::setScope(Scope * scope) + { + scope_ = scope; + } +} diff --git a/tests/lang/mugiwara/input/pointers/index-arith.mgw b/tests/lang/mugiwara/input/pointers/index-arith.mgw new file mode 100644 index 0000000..7a2edeb --- /dev/null +++ b/tests/lang/mugiwara/input/pointers/index-arith.mgw @@ -0,0 +1,4 @@ +int32 main(int32 argc, **int8 argv) +{ + return ((argv + 1)* + 2)*; +} -- 2.11.4.GIT