diff --git a/CMakeLists.txt b/CMakeLists.txt index 92fd8be..1e0498a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,7 +19,6 @@ include_directories("${CMAKE_SOURCE_DIR}/include/") add_library(AST SHARED src/ast/AddressOf.cpp src/ast/Allocation.cpp - src/ast/ArrayAccess.cpp src/ast/ArrayType.cpp src/ast/Assign.cpp src/ast/BaseType.cpp @@ -30,6 +29,7 @@ add_library(AST SHARED src/ast/ClassType.cpp src/ast/ClassTypeDecl.cpp src/ast/ClassTypeDef.cpp + src/ast/ConstructorCall.cpp src/ast/ConstructorDecl.cpp src/ast/ConstructorDef.cpp src/ast/Deletion.cpp @@ -54,9 +54,9 @@ add_library(AST SHARED src/ast/Program.cpp src/ast/ReferenceType.cpp src/ast/Return.cpp - src/ast/Scope.cpp src/ast/SizeOf.cpp src/ast/StringLiteral.cpp + src/ast/SubscriptOp.cpp src/ast/TertiaryExpr.cpp src/ast/Throw.cpp src/ast/TypeCast.cpp diff --git a/README.md b/README.md index 1f8db6f..4f2a83f 100644 --- a/README.md +++ b/README.md @@ -107,6 +107,7 @@ Progressively changing to adopt new features of the language(s). | "new" type [ "(" litExpr ("," litExpr)* ")" ] ";" | "&" objExpr | "!" objExpr + | objExpr "[" expr "] | objExpr objExpr -> funCall (objExprOp)* @@ -131,8 +132,8 @@ Progressively changing to adopt new features of the language(s). | STRING_LITERAL | "true" | "false" - | "(" exp ")" - | exp + | "(" expr ")" + | expr * * * diff --git a/include/AST.h b/include/AST.h index 522070b..82d5c94 100644 --- a/include/AST.h +++ b/include/AST.h @@ -4,7 +4,6 @@ #include "ast/AddressOf.h" #include "ast/Allocation.h" -#include "ast/ArrayAccess.h" #include "ast/ArrayType.h" #include "ast/Assign.h" #include "ast/BaseType.h" @@ -15,6 +14,7 @@ #include "ast/ClassType.h" #include "ast/ClassTypeDecl.h" #include "ast/ClassTypeDef.h" +#include "ast/ConstructorCall.h" #include "ast/ConstructorDecl.h" #include "ast/ConstructorDef.h" #include "ast/Decl.h" @@ -47,6 +47,7 @@ #include "ast/SizeOf.h" #include "ast/Stmt.h" #include "ast/StringLiteral.h" +#include "ast/SubscriptOp.h" #include "ast/TertiaryExpr.h" #include "ast/Throw.h" #include "ast/Type.h" diff --git a/include/ASTVisitor.h b/include/ASTVisitor.h index 66101b1..017e1df 100644 --- a/include/ASTVisitor.h +++ b/include/ASTVisitor.h @@ -4,7 +4,6 @@ namespace ACC { class AddressOf; class Allocation; -class ArrayAccess; class ArrayType; class Assign; class BaseType; @@ -15,6 +14,7 @@ class CharLiteral; class ClassType; class ClassTypeDecl; class ClassTypeDef; +class ConstructorCall; class ConstructorDecl; class ConstructorDef; class Deletion; @@ -41,6 +41,7 @@ class ReferenceType; class Return; class SizeOf; class StringLiteral; +class SubscriptOp; class TertiaryExpr; class Throw; class TypeCast; @@ -58,7 +59,6 @@ template class ASTVisitor { virtual T visit(AddressOf &ao) = 0; virtual T visit(Allocation &a) = 0; - virtual T visit(ArrayAccess &aa) = 0; virtual T visit(ArrayType &at) = 0; virtual T visit(Assign &as) = 0; virtual T visit(BaseType &bt) = 0; @@ -69,6 +69,7 @@ template class ASTVisitor { virtual T visit(ClassType &ct) = 0; virtual T visit(ClassTypeDecl &ctd) = 0; virtual T visit(ClassTypeDef &ctd) = 0; + virtual T visit(ConstructorCall &cc) = 0; virtual T visit(ConstructorDecl &cd) = 0; virtual T visit(ConstructorDef &cd) = 0; virtual T visit(Deletion &d) = 0; @@ -95,6 +96,7 @@ template class ASTVisitor { virtual T visit(Return &r) = 0; virtual T visit(SizeOf &so) = 0; virtual T visit(StringLiteral &sl) = 0; + virtual T visit(SubscriptOp &so) = 0; virtual T visit(TertiaryExpr &t) = 0; virtual T visit(Throw &t) = 0; virtual T visit(TypeCast &tc) = 0; diff --git a/include/ast/AddressOf.h b/include/ast/AddressOf.h index d6ba612..9e123c8 100644 --- a/include/ast/AddressOf.h +++ b/include/ast/AddressOf.h @@ -12,8 +12,6 @@ class AddressOf : public Expr, public atl::enable_shared_from_this { AddressOf(const atl::shared_ptr &p_addressOfExpr); - atl::string getSignature() const override; - bool operator==(Expr &rhs) const override; bool operator!=(Expr &rhs) const override; diff --git a/include/ast/Allocation.h b/include/ast/Allocation.h index 26e6085..6dc2369 100644 --- a/include/ast/Allocation.h +++ b/include/ast/Allocation.h @@ -18,8 +18,7 @@ class Allocation : public Expr, virtual ~Allocation() {} - atl::string getSignature() const override; - + bool operator==(Expr &rhs) const override; bool operator!=(Expr &rhs) const override; diff --git a/include/ast/ArrayAccess.h b/include/ast/ArrayAccess.h deleted file mode 100644 index 4b675a9..0000000 --- a/include/ast/ArrayAccess.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -#include "Expr.h" -#include "Type.h" - -namespace ACC { - -class ArrayAccess : public Expr, - public atl::enable_shared_from_this { - -public: - atl::shared_ptr array; - atl::shared_ptr index; - - ArrayAccess(const atl::shared_ptr &p_array, - const atl::shared_ptr &p_index); - - atl::string getSignature() const override; - - bool operator==(Expr &rhs) const override; - bool operator!=(Expr &rhs) const override; - - bool operator==(const ArrayAccess &rhs) const; - bool operator!=(const ArrayAccess &rhs) const; - - atl::shared_ptr getptr() { return shared_from_this(); } - - atl::string astClass() const override { return "ArrayAccess"; } - - VISITOR_ACCEPTORS -}; - -} // namespace ACC diff --git a/include/ast/ArrayType.h b/include/ast/ArrayType.h index 3dae6f2..46f73c3 100644 --- a/include/ast/ArrayType.h +++ b/include/ast/ArrayType.h @@ -13,11 +13,9 @@ class ArrayType : public PointerType { ArrayType(const atl::shared_ptr &p_type, const atl::shared_ptr &p_size); - int getBytes() const override; + unsigned int getBytes() const override; - atl::string getSignature() const override; - - bool operator==(Type &rhs) const override; + bool operator==(Type &rhs) const override; bool operator!=(Type &rhs) const override; bool operator==(const ArrayType &rhs) const; diff --git a/include/ast/BaseType.h b/include/ast/BaseType.h index ff31f6b..b5f6ae7 100644 --- a/include/ast/BaseType.h +++ b/include/ast/BaseType.h @@ -12,11 +12,9 @@ class BaseType : public Type, public atl::enable_shared_from_this { BaseType(const PrimitiveType p_pType); - int getBytes() const override; + unsigned int getBytes() const override; - atl::string getSignature() const override; - - bool operator==(Type &rhs) const override; + bool operator==(Type &rhs) const override; bool operator!=(Type &rhs) const override; bool operator==(const BaseType &rhs) const; diff --git a/include/ast/BinOp.h b/include/ast/BinOp.h index 4633c45..0929db5 100644 --- a/include/ast/BinOp.h +++ b/include/ast/BinOp.h @@ -16,8 +16,7 @@ class BinOp : public Expr, public atl::enable_shared_from_this { BinOp(const atl::shared_ptr &p_lhs, const Op p_operation, const atl::shared_ptr &p_rhs); - atl::string getSignature() const override; - + bool operator==(Expr &rhs) const override; bool operator!=(Expr &rhs) const override; diff --git a/include/ast/Block.h b/include/ast/Block.h index 6d5fc35..7e01bd8 100644 --- a/include/ast/Block.h +++ b/include/ast/Block.h @@ -12,6 +12,7 @@ class Block : public Stmt, public atl::enable_shared_from_this { public: + unsigned int stmtsChecked = 0; atl::vector> stmts; Block(const atl::vector> &p_stmts); @@ -23,6 +24,31 @@ class Block : public Stmt, atl::string astClass() const override { return "Block"; } + /* Scope Methods */ + virtual atl::shared_ptr findClassDecl( + const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr findClassDef( + const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr + findFunDecl(const FunSignature &funSignature, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr findFunDeclLocal( + const FunSignature &funSignature, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr + findVarDecl(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr findVarDeclLocal( + const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl = nullptr) const override; + VISITOR_ACCEPTORS }; diff --git a/include/ast/BoolLiteral.h b/include/ast/BoolLiteral.h index f5c02b8..6518278 100644 --- a/include/ast/BoolLiteral.h +++ b/include/ast/BoolLiteral.h @@ -11,8 +11,7 @@ class BoolLiteral : public Literal, public: BoolLiteral(const atl::string &p_literal); - atl::string getSignature() const override; - + bool operator==(Expr &rhs) const override; bool operator!=(Expr &rhs) const override; diff --git a/include/ast/CharLiteral.h b/include/ast/CharLiteral.h index 6c527d9..84b5f1a 100644 --- a/include/ast/CharLiteral.h +++ b/include/ast/CharLiteral.h @@ -11,8 +11,7 @@ class CharLiteral : public Literal, public: CharLiteral(const atl::string &p_literal); - atl::string getSignature() const override; - + bool operator==(Expr &rhs) const override; bool operator!=(Expr &rhs) const override; diff --git a/include/ast/ClassType.h b/include/ast/ClassType.h index 16e834b..592ec1a 100644 --- a/include/ast/ClassType.h +++ b/include/ast/ClassType.h @@ -15,9 +15,7 @@ class ClassType : public Type, public atl::enable_shared_from_this { ClassType(const atl::shared_ptr &p_identifier); - int getBytes() const override; - - atl::string getSignature() const override; + unsigned int getBytes() const override; bool operator==(Type &rhs) const override; bool operator!=(Type &rhs) const override; diff --git a/include/ast/ClassTypeDecl.h b/include/ast/ClassTypeDecl.h index 37b7b1b..e7de136 100644 --- a/include/ast/ClassTypeDecl.h +++ b/include/ast/ClassTypeDecl.h @@ -28,6 +28,31 @@ class ClassTypeDecl : public Decl, atl::string astClass() const override { return "ClassTypeDecl"; } + /* Scope Methods */ + virtual atl::shared_ptr findClassDecl( + const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr findClassDef( + const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr + findFunDecl(const FunSignature &funSignature, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr findFunDeclLocal( + const FunSignature &funSignature, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr + findVarDecl(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr findVarDeclLocal( + const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl = nullptr) const override; + VISITOR_ACCEPTORS }; diff --git a/include/ast/ClassTypeDef.h b/include/ast/ClassTypeDef.h index b4bd50b..61d17c4 100644 --- a/include/ast/ClassTypeDef.h +++ b/include/ast/ClassTypeDef.h @@ -26,6 +26,35 @@ class ClassTypeDef : public ClassTypeDecl { atl::string astClass() const override { return "ClassTypeDef"; } + /* Scope Methods */ + virtual atl::shared_ptr findClassDecl( + const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr findClassDef( + const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + atl::shared_ptr + findConstructorDecl(const FunSignature &ctorSignature, + const atl::shared_ptr &exemptDecl = nullptr) const; + + virtual atl::shared_ptr + findFunDecl(const FunSignature &funSignature, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr findFunDeclLocal( + const FunSignature &funSignature, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr + findVarDecl(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr findVarDeclLocal( + const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl = nullptr) const override; + VISITOR_ACCEPTORS }; diff --git a/include/ast/ConstructorCall.h b/include/ast/ConstructorCall.h new file mode 100644 index 0000000..61a638a --- /dev/null +++ b/include/ast/ConstructorCall.h @@ -0,0 +1,34 @@ +#pragma once + +#include "ConstructorDecl.h" +#include "Expr.h" +#include "Identifier.h" +#include "Type.h" + +namespace ACC { + +class ConstructorCall : public Expr, + public atl::enable_shared_from_this { + +public: + atl::shared_ptr constructorIdentifier; + atl::vector> constructorArgs; + atl::shared_ptr constructorDecl; + + ConstructorCall(const atl::shared_ptr &p_ctorIdentifier, + const atl::vector> &p_ctorArgs); + + bool operator==(Expr &rhs) const override; + bool operator!=(Expr &rhs) const override; + + bool operator==(const ConstructorCall &rhs) const; + bool operator!=(const ConstructorCall &rhs) const; + + atl::shared_ptr getptr() { return shared_from_this(); } + + atl::string astClass() const override { return "ConstructorCall"; } + + VISITOR_ACCEPTORS +}; + +} // namespace ACC diff --git a/include/ast/ConstructorDecl.h b/include/ast/ConstructorDecl.h index 18b0c20..23b3adf 100644 --- a/include/ast/ConstructorDecl.h +++ b/include/ast/ConstructorDecl.h @@ -22,6 +22,7 @@ class ConstructorDecl : public Decl, virtual ~ConstructorDecl() {} atl::shared_ptr getIdentifier() const override; + const FunSignature getSignature() const; bool operator==(Decl &rhs) const override; bool operator!=(Decl &rhs) const override; @@ -33,6 +34,31 @@ class ConstructorDecl : public Decl, atl::string astClass() const override { return "ConstructorDecl"; } + /* Scope Methods */ + virtual atl::shared_ptr findClassDecl( + const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr findClassDef( + const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr + findFunDecl(const FunSignature &funSignature, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr findFunDeclLocal( + const FunSignature &funSignature, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr + findVarDecl(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr findVarDeclLocal( + const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl = nullptr) const override; + VISITOR_ACCEPTORS }; diff --git a/include/ast/ConstructorDef.h b/include/ast/ConstructorDef.h index a98b7fa..56c3c08 100644 --- a/include/ast/ConstructorDef.h +++ b/include/ast/ConstructorDef.h @@ -34,6 +34,31 @@ class ConstructorDef : public ConstructorDecl { atl::string astClass() const override { return "ConstructorDef"; } + /* Scope Methods */ + virtual atl::shared_ptr findClassDecl( + const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr findClassDef( + const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr + findFunDecl(const FunSignature &funSignature, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr findFunDeclLocal( + const FunSignature &funSignature, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr + findVarDecl(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr findVarDeclLocal( + const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl = nullptr) const override; + VISITOR_ACCEPTORS }; diff --git a/include/ast/Decl.h b/include/ast/Decl.h index cf94d25..07a8ca2 100644 --- a/include/ast/Decl.h +++ b/include/ast/Decl.h @@ -9,9 +9,10 @@ class Decl : public ASTNode { public: enum class Visibility { PUBLIC, PRIVATE, PROTECTED, NONE }; + atl::shared_ptr outerDecl; Visibility visibility; - Decl() : visibility(Visibility::NONE) {} + Decl() : outerDecl(nullptr), visibility(Visibility::NONE) {} Decl(const Visibility &p_visibility) : visibility(p_visibility) {} virtual ~Decl() {} virtual bool operator==(Decl &rhs) const = 0; diff --git a/include/ast/Expr.h b/include/ast/Expr.h index 6775eb4..5715106 100644 --- a/include/ast/Expr.h +++ b/include/ast/Expr.h @@ -7,7 +7,6 @@ namespace ACC { class Expr : public Stmt { public: virtual ~Expr() {} - virtual atl::string getSignature() const = 0; virtual bool operator==(Expr &rhs) const = 0; virtual bool operator!=(Expr &rhs) const = 0; }; diff --git a/include/ast/For.h b/include/ast/For.h index b2556a6..da4aae2 100644 --- a/include/ast/For.h +++ b/include/ast/For.h @@ -26,6 +26,31 @@ class For : public Stmt, atl::string astClass() const override { return "For"; } + /* Scope Methods */ + virtual atl::shared_ptr findClassDecl( + const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr findClassDef( + const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr + findFunDecl(const FunSignature &funSignature, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr findFunDeclLocal( + const FunSignature &funSignature, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr + findVarDecl(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr findVarDeclLocal( + const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl = nullptr) const override; + VISITOR_ACCEPTORS }; diff --git a/include/ast/FunCall.h b/include/ast/FunCall.h index d053990..41cd603 100644 --- a/include/ast/FunCall.h +++ b/include/ast/FunCall.h @@ -17,8 +17,6 @@ class FunCall : public Expr, public atl::enable_shared_from_this { FunCall(const atl::shared_ptr &p_funIdentifier, const atl::vector> &p_funArgs); - atl::string getSignature() const override; - bool operator==(Expr &rhs) const override; bool operator!=(Expr &rhs) const override; diff --git a/include/ast/FunDecl.h b/include/ast/FunDecl.h index 82ca1c0..c6911d4 100644 --- a/include/ast/FunDecl.h +++ b/include/ast/FunDecl.h @@ -1,6 +1,7 @@ #pragma once #include "Decl.h" +#include "FunSignature.h" #include "Scope.h" #include "Type.h" #include "VarDecl.h" @@ -24,7 +25,7 @@ class FunDecl : public Decl, const atl::shared_ptr &p_funType); atl::shared_ptr getIdentifier() const override; - atl::string getSignature() const; + const FunSignature getSignature() const; bool operator==(Decl &rhs) const override; bool operator!=(Decl &rhs) const override; @@ -36,6 +37,31 @@ class FunDecl : public Decl, atl::string astClass() const override { return "FunDecl"; } + /* Scope Methods */ + virtual atl::shared_ptr findClassDecl( + const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr findClassDef( + const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr + findFunDecl(const FunSignature &funSignature, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr findFunDeclLocal( + const FunSignature &funSignature, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr + findVarDecl(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr findVarDeclLocal( + const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl = nullptr) const override; + VISITOR_ACCEPTORS }; diff --git a/include/ast/FunDef.h b/include/ast/FunDef.h index ee63521..7067680 100644 --- a/include/ast/FunDef.h +++ b/include/ast/FunDef.h @@ -34,6 +34,31 @@ class FunDef : public FunDecl { atl::string astClass() const override { return "FunDef"; } + /* Scope Methods */ + virtual atl::shared_ptr findClassDecl( + const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr findClassDef( + const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr + findFunDecl(const FunSignature &funSignature, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr findFunDeclLocal( + const FunSignature &funSignature, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr + findVarDecl(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr findVarDeclLocal( + const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl = nullptr) const override; + VISITOR_ACCEPTORS }; diff --git a/include/ast/FunSignature.h b/include/ast/FunSignature.h new file mode 100644 index 0000000..324783f --- /dev/null +++ b/include/ast/FunSignature.h @@ -0,0 +1,54 @@ +#pragma once + +#include "atl/include/shared_ptr.h" +#include "atl/include/vector.h" + +#include "ast/Identifier.h" +#include "ast/Type.h" + +namespace ACC { + +class FunSignature { +public: + FunSignature(const atl::shared_ptr p_funReturnType, + const atl::shared_ptr p_funIdentifier, + const atl::vector> p_funArgs) + : funReturnType(p_funReturnType), funIdentifier(p_funIdentifier), + funArgs(p_funArgs) {} + + const unsigned int namespaceCount() const { + return funIdentifier->namespaceCount(); + } + + const atl::shared_ptr namespaceHead() const { + return funIdentifier->namespaceHead(); + } + + const FunSignature lowerNamespace() const { + return FunSignature(funReturnType, funIdentifier->namespaceTail(), funArgs); + } + + bool operator==(const FunSignature &rhs) const { + // TODO: Incorporate return type? + + // Check args match. + for (int idx = 0; idx < funArgs.size(); ++idx) + if (*funArgs[idx] != *rhs.funArgs[idx]) + return false; + + // Check identifier. + if (*funIdentifier != *rhs.funIdentifier) + return false; + + return true; + } + + bool operator!=(const FunSignature &rhs) const { return !(*this == rhs); } + +private: + const atl::shared_ptr funReturnType; + const atl::shared_ptr funIdentifier; + const atl::vector> funArgs; +}; + +} // namespace ACC \ No newline at end of file diff --git a/include/ast/Identifier.h b/include/ast/Identifier.h index 9d17052..dc1e588 100644 --- a/include/ast/Identifier.h +++ b/include/ast/Identifier.h @@ -25,6 +25,10 @@ class Identifier : public ASTNode, Identifier(const Identifier &) = delete; + const unsigned int namespaceCount() const; + const atl::shared_ptr namespaceHead() const; + const atl::shared_ptr namespaceTail() const; + atl::string toString() const; atl::shared_ptr getptr() { return shared_from_this(); } @@ -35,6 +39,10 @@ class Identifier : public ASTNode, atl::string astClass() const override { return "Identifier"; } VISITOR_ACCEPTORS + +private: + const atl::shared_ptr + deepCopyIdentifier(const unsigned int depth) const; }; } // namespace ACC diff --git a/include/ast/IntLiteral.h b/include/ast/IntLiteral.h index c51dde1..ce5e60a 100644 --- a/include/ast/IntLiteral.h +++ b/include/ast/IntLiteral.h @@ -9,12 +9,12 @@ namespace ACC { class IntLiteral : public Literal, public atl::enable_shared_from_this { public: + bool isUnsigned; + IntLiteral(const atl::string &p_literal); atl::string getLiteral() const override { return value; } - atl::string getSignature() const override { return "int"; } - bool operator==(Expr &rhs) const override; bool operator!=(Expr &rhs) const override; @@ -29,6 +29,18 @@ class IntLiteral : public Literal, atl::string astClass() const override { return "IntLiteral"; } VISITOR_ACCEPTORS + +private: + static atl::string removeSigned(const atl::string &val) { + if (val[val.size() - 1] == 'u') { + atl::string unsignedVal; + for (unsigned int idx = 0; idx < val.size() - 1; ++idx) { + unsignedVal += val[idx]; + } + return unsignedVal; + } + return val; + } }; } // namespace ACC diff --git a/include/ast/MemberAccess.h b/include/ast/MemberAccess.h index be75a18..14194f1 100644 --- a/include/ast/MemberAccess.h +++ b/include/ast/MemberAccess.h @@ -20,8 +20,7 @@ class MemberAccess : public Expr, const atl::shared_ptr &p_fieldVariable, const SourceToken::Class &p_accessType); - atl::string getSignature() const override; - + bool operator==(Expr &rhs) const override; bool operator!=(Expr &rhs) const override; diff --git a/include/ast/MemberCall.h b/include/ast/MemberCall.h index f533ea0..87d525c 100644 --- a/include/ast/MemberCall.h +++ b/include/ast/MemberCall.h @@ -19,8 +19,7 @@ class MemberCall : public Expr, const atl::shared_ptr &p_funCall, const SourceToken::Class &p_accessType); - atl::string getSignature() const override; - + bool operator==(Expr &rhs) const override; bool operator!=(Expr &rhs) const override; diff --git a/include/ast/Namespace.h b/include/ast/Namespace.h index dfef649..04301bb 100644 --- a/include/ast/Namespace.h +++ b/include/ast/Namespace.h @@ -10,6 +10,7 @@ class Namespace : public Decl, public atl::enable_shared_from_this { public: + unsigned int namespaceDeclsChecked = 0; atl::shared_ptr identifier; atl::vector> namespaceDecls; @@ -28,6 +29,31 @@ class Namespace : public Decl, atl::string astClass() const override { return "Namespace"; } + /* Scope Methods */ + virtual atl::shared_ptr findClassDecl( + const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr findClassDef( + const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr + findFunDecl(const FunSignature &funSignature, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr findFunDeclLocal( + const FunSignature &funSignature, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr + findVarDecl(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr findVarDeclLocal( + const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl = nullptr) const override; + VISITOR_ACCEPTORS }; } // namespace ACC diff --git a/include/ast/Nullptr.h b/include/ast/Nullptr.h index 42e557f..7d51851 100644 --- a/include/ast/Nullptr.h +++ b/include/ast/Nullptr.h @@ -12,8 +12,6 @@ class Nullptr : public Expr, public atl::enable_shared_from_this { Nullptr(); - atl::string getSignature() const override { return "nullptr_t"; } - bool operator==(Expr &rhs) const override; bool operator!=(Expr &rhs) const override; diff --git a/include/ast/ParenthExpr.h b/include/ast/ParenthExpr.h index d0cb72d..08bdbfc 100644 --- a/include/ast/ParenthExpr.h +++ b/include/ast/ParenthExpr.h @@ -13,8 +13,6 @@ class ParenthExpr : public Expr, ParenthExpr(const atl::shared_ptr &p_innerExpr); - atl::string getSignature() const override { return innerExpr->getSignature(); } - bool operator==(Expr &rhs) const override; bool operator!=(Expr &rhs) const override; diff --git a/include/ast/PointerType.h b/include/ast/PointerType.h index d1bfc04..1ea8751 100644 --- a/include/ast/PointerType.h +++ b/include/ast/PointerType.h @@ -14,11 +14,9 @@ class PointerType : public Type, PointerType(const atl::shared_ptr &p_pointedType); virtual ~PointerType() {} - virtual int getBytes() const override; + virtual unsigned int getBytes() const override; - atl::string getSignature() const override; - - virtual bool operator==(Type &rhs) const override; + virtual bool operator==(Type &rhs) const override; virtual bool operator!=(Type &rhs) const override; bool operator==(const PointerType &rhs) const; diff --git a/include/ast/PrefixOp.h b/include/ast/PrefixOp.h index 1d118cd..fa09851 100644 --- a/include/ast/PrefixOp.h +++ b/include/ast/PrefixOp.h @@ -15,8 +15,7 @@ class PrefixOp : public Expr, public atl::enable_shared_from_this { PrefixOp(const Op p_operation, const atl::shared_ptr &p_variable); virtual ~PrefixOp() {} - atl::string getSignature() const override; - + bool operator==(Expr &rhs) const override; bool operator!=(Expr &rhs) const override; diff --git a/include/ast/Program.h b/include/ast/Program.h index 4d0f12e..247e310 100644 --- a/include/ast/Program.h +++ b/include/ast/Program.h @@ -3,25 +3,54 @@ #include "atl/include/unordered_map.h" #include "ASTNode.h" -#include "ast/FunDecl.h" -#include "ast/Namespace.h" -#include "ast/VarDecl.h" +#include "ClassTypeDef.h" +#include "FunDef.h" +#include "Namespace.h" +#include "VarDef.h" namespace ACC { -class Program : public ASTNode { +class Program : public ASTNode, + public Scope, + public atl::enable_shared_from_this { public: + unsigned int declsChecked = 0; atl::vector> decls; atl::vector> funDecls; atl::vector> globalVars; - atl::shared_ptr globalScope; - atl::unordered_map namespaces; Program(const atl::vector> &p_decls); + atl::shared_ptr getptr() { return shared_from_this(); } + atl::string astClass() const override { return "Program"; } + /* Scope Methods */ + virtual atl::shared_ptr findClassDecl( + const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr findClassDef( + const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr + findFunDecl(const FunSignature &funSignature, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr findFunDeclLocal( + const FunSignature &funSignature, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr + findVarDecl(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl = nullptr) const override; + + virtual atl::shared_ptr findVarDeclLocal( + const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl = nullptr) const override; + VISITOR_ACCEPTORS }; } // namespace ACC diff --git a/include/ast/ReferenceType.h b/include/ast/ReferenceType.h index b9b1059..746f82b 100644 --- a/include/ast/ReferenceType.h +++ b/include/ast/ReferenceType.h @@ -13,11 +13,9 @@ class ReferenceType : public Type, ReferenceType(const atl::shared_ptr &p_referencedType); - int getBytes() const override; + unsigned int getBytes() const override; - atl::string getSignature() const override; - - bool operator==(Type &rhs) const override; + bool operator==(Type &rhs) const override; bool operator!=(Type &rhs) const override; bool operator==(const ReferenceType &rhs) const; diff --git a/include/ast/Scope.h b/include/ast/Scope.h index 792f986..033fec7 100644 --- a/include/ast/Scope.h +++ b/include/ast/Scope.h @@ -1,49 +1,39 @@ #pragma once #include "Decl.h" +#include "FunSignature.h" namespace ACC { class Scope { public: - atl::vector> decls; atl::shared_ptr outerScope; - Scope(); + Scope() : outerScope(nullptr) {} virtual ~Scope() {} - atl::shared_ptr - findClassDecl(const atl::shared_ptr identifier) const; + virtual atl::shared_ptr + findClassDecl(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl = nullptr) const = 0; - atl::shared_ptr - findClassDef(const atl::shared_ptr identifier) const; + virtual atl::shared_ptr + findClassDef(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl = nullptr) const = 0; - atl::shared_ptr findFunDecl(const atl::string &funSignature) const; + virtual atl::shared_ptr + findFunDecl(const FunSignature &funSignature, + const atl::shared_ptr &exemptDecl = nullptr) const = 0; - atl::shared_ptr - findFunDeclLocal(const atl::string &funSignature) const; + virtual atl::shared_ptr + findFunDeclLocal(const FunSignature &funSignature, + const atl::shared_ptr &exemptDecl = nullptr) const = 0; - atl::shared_ptr - findVarDecl(const atl::shared_ptr identifier) const; + virtual atl::shared_ptr + findVarDecl(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl = nullptr) const = 0; - atl::shared_ptr - findVarDeclLocal(const atl::shared_ptr identifier) const; - - /* Old */ - - void insertDecl(const atl::shared_ptr &decl); - - atl::shared_ptr - resolveClassType(const atl::shared_ptr &type) const; - - atl::shared_ptr - resolveVarExpr(const atl::shared_ptr identifier) const; - atl::shared_ptr resolveFunCall(const atl::string funSignature) const; - - atl::shared_ptr - duplicateDeclaration(const atl::shared_ptr &decl) const; - - atl::shared_ptr - duplicateDeclarationLocal(const atl::shared_ptr &decl) const; + virtual atl::shared_ptr + findVarDeclLocal(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl = nullptr) const = 0; }; } // namespace ACC diff --git a/include/ast/SizeOf.h b/include/ast/SizeOf.h index 36de50a..c21a372 100644 --- a/include/ast/SizeOf.h +++ b/include/ast/SizeOf.h @@ -12,8 +12,7 @@ class SizeOf : public Expr, public atl::enable_shared_from_this { SizeOf(const atl::shared_ptr &p_type); - atl::string getSignature() const override; - + bool operator==(Expr &rhs) const override; bool operator!=(Expr &rhs) const override; diff --git a/include/ast/StringLiteral.h b/include/ast/StringLiteral.h index 8f95163..7870c4a 100644 --- a/include/ast/StringLiteral.h +++ b/include/ast/StringLiteral.h @@ -11,8 +11,7 @@ class StringLiteral : public Literal, public: StringLiteral(const atl::string &p_literal); - atl::string getSignature() const override; - + bool operator==(Expr &rhs) const override; bool operator!=(Expr &rhs) const override; diff --git a/include/ast/SubscriptOp.h b/include/ast/SubscriptOp.h new file mode 100644 index 0000000..68467bf --- /dev/null +++ b/include/ast/SubscriptOp.h @@ -0,0 +1,34 @@ +#pragma once + +#include "Expr.h" +#include "FunDef.h" +#include "VarExpr.h" + +namespace ACC { + +class SubscriptOp : public Expr, + public atl::enable_shared_from_this { +public: + atl::shared_ptr variable; + atl::shared_ptr index; + atl::shared_ptr operatorDecl; + + SubscriptOp(const atl::shared_ptr &p_variable, + const atl::shared_ptr &p_index); + virtual ~SubscriptOp() {} + + + bool operator==(Expr &rhs) const override; + bool operator!=(Expr &rhs) const override; + + bool operator==(const SubscriptOp &rhs) const; + bool operator!=(const SubscriptOp &rhs) const; + + atl::shared_ptr getptr() { return shared_from_this(); } + + atl::string astClass() const override { return "SubscriptOp"; } + + VISITOR_ACCEPTORS +}; + +} // namespace ACC diff --git a/include/ast/TertiaryExpr.h b/include/ast/TertiaryExpr.h index f326d80..36c9488 100644 --- a/include/ast/TertiaryExpr.h +++ b/include/ast/TertiaryExpr.h @@ -17,8 +17,7 @@ class TertiaryExpr : public Expr, const atl::shared_ptr &p_tertiaryIfBody, const atl::shared_ptr &p_tertiaryElseBody); - atl::string getSignature() const override; - + bool operator==(Expr &rhs) const override; bool operator!=(Expr &rhs) const override; diff --git a/include/ast/Type.h b/include/ast/Type.h index e0edaa7..c5d37ea 100644 --- a/include/ast/Type.h +++ b/include/ast/Type.h @@ -10,8 +10,7 @@ class Type : public ASTNode { enum class Modifiers { CONST }; atl::set typeModifiers; virtual ~Type() {} - virtual int getBytes() const = 0; - virtual atl::string getSignature() const = 0; + virtual unsigned int getBytes() const = 0; virtual bool operator==(Type &rhs) const = 0; virtual bool operator!=(Type &rhs) const = 0; }; diff --git a/include/ast/TypeCast.h b/include/ast/TypeCast.h index 69f1528..6b84743 100644 --- a/include/ast/TypeCast.h +++ b/include/ast/TypeCast.h @@ -14,8 +14,7 @@ class TypeCast : public Expr, public atl::enable_shared_from_this { TypeCast(const atl::shared_ptr &p_type, const atl::shared_ptr &p_expr); - atl::string getSignature() const override; - + bool operator==(Expr &rhs) const override; bool operator!=(Expr &rhs) const override; diff --git a/include/ast/ValueAt.h b/include/ast/ValueAt.h index 207d040..9cb9b74 100644 --- a/include/ast/ValueAt.h +++ b/include/ast/ValueAt.h @@ -12,8 +12,7 @@ class ValueAt : public Expr, public atl::enable_shared_from_this { ValueAt(const atl::shared_ptr &p_derefExpr); - atl::string getSignature() const override; - + bool operator==(Expr &rhs) const override; bool operator!=(Expr &rhs) const override; diff --git a/include/ast/VarDecl.h b/include/ast/VarDecl.h index d13106c..c779857 100644 --- a/include/ast/VarDecl.h +++ b/include/ast/VarDecl.h @@ -23,7 +23,7 @@ class VarDecl : public Decl, VarDecl(const atl::shared_ptr &p_type, const atl::shared_ptr &p_identifier); - int getBytes() const; + unsigned int getBytes() const; atl::shared_ptr getIdentifier() const override; diff --git a/include/ast/VarDef.h b/include/ast/VarDef.h index 30e2f4b..8487a3a 100644 --- a/include/ast/VarDef.h +++ b/include/ast/VarDef.h @@ -19,7 +19,7 @@ class VarDef : public VarDecl { const atl::shared_ptr &p_varidentifier, const atl::shared_ptr &p_varValue); - int getBytes() const; + unsigned int getBytes() const; atl::shared_ptr getIdentifier() const override; diff --git a/include/ast/VarExpr.h b/include/ast/VarExpr.h index 9ef23d4..080c8bf 100644 --- a/include/ast/VarExpr.h +++ b/include/ast/VarExpr.h @@ -14,8 +14,6 @@ class VarExpr : public Expr, public atl::enable_shared_from_this { VarExpr(const atl::shared_ptr &p_varIdentifier); - atl::string getSignature() const override { return varDecl->type->getSignature(); } - bool operator==(Expr &rhs) const override; bool operator!=(Expr &rhs) const override; diff --git a/include/passes/DotGraph.h b/include/passes/DotGraph.h index 27a2513..4de0e71 100644 --- a/include/passes/DotGraph.h +++ b/include/passes/DotGraph.h @@ -26,7 +26,6 @@ class DotGraph : public ASTVisitor { atl::string visit(AddressOf &ao) override; atl::string visit(Allocation &a) override; - atl::string visit(ArrayAccess &aa) override; atl::string visit(ArrayType &at) override; atl::string visit(Assign &as) override; atl::string visit(BaseType &bt) override; @@ -37,6 +36,7 @@ class DotGraph : public ASTVisitor { atl::string visit(ClassType &ct) override; atl::string visit(ClassTypeDecl &ctd) override; atl::string visit(ClassTypeDef &ctd) override; + atl::string visit(ConstructorCall &cc) override; atl::string visit(ConstructorDecl &cd) override; atl::string visit(ConstructorDef &cd) override; atl::string visit(Deletion &d) override; @@ -63,6 +63,7 @@ class DotGraph : public ASTVisitor { atl::string visit(Return &r) override; atl::string visit(SizeOf &so) override; atl::string visit(StringLiteral &sl) override; + atl::string visit(SubscriptOp &so) override; atl::string visit(TertiaryExpr &t) override; atl::string visit(Throw &t) override; atl::string visit(TypeCast &tc) override; diff --git a/include/passes/Optimiser.h b/include/passes/Optimiser.h index 4742bc3..49ddf4e 100644 --- a/include/passes/Optimiser.h +++ b/include/passes/Optimiser.h @@ -23,13 +23,12 @@ class Optimiser : public ASTVisitor> { private: atl::shared_ptr &progAST; - atl::shared_ptr currScope; + atl::shared_ptr currScope; /* ---- Visit AST ---- */ atl::shared_ptr visit(AddressOf &ao) override; atl::shared_ptr visit(Allocation &a) override; - atl::shared_ptr visit(ArrayAccess &aa) override; atl::shared_ptr visit(ArrayType &at) override; atl::shared_ptr visit(Assign &as) override; atl::shared_ptr visit(BaseType &bt) override; @@ -40,6 +39,7 @@ class Optimiser : public ASTVisitor> { atl::shared_ptr visit(ClassType &ct) override; atl::shared_ptr visit(ClassTypeDecl &ctd) override; atl::shared_ptr visit(ClassTypeDef &ctd) override; + atl::shared_ptr visit(ConstructorCall &cc) override; atl::shared_ptr visit(ConstructorDecl &cd) override; atl::shared_ptr visit(ConstructorDef &cd) override; atl::shared_ptr visit(Deletion &d) override; @@ -66,6 +66,7 @@ class Optimiser : public ASTVisitor> { atl::shared_ptr visit(Return &r) override; atl::shared_ptr visit(SizeOf &so) override; atl::shared_ptr visit(StringLiteral &sl) override; + atl::shared_ptr visit(SubscriptOp &so) override; atl::shared_ptr visit(TertiaryExpr &t) override; atl::shared_ptr visit(Throw &t) override; atl::shared_ptr visit(TypeCast &tc) override; diff --git a/include/passes/SemanticAnalysis.h b/include/passes/SemanticAnalysis.h index 8b5dc22..4b6f008 100644 --- a/include/passes/SemanticAnalysis.h +++ b/include/passes/SemanticAnalysis.h @@ -25,14 +25,10 @@ class SemanticAnalysis : public ASTVisitor> { atl::shared_ptr progAST; atl::shared_ptr currScope; - // Too lazy to make MemberFunDecl/MemberFunDef ASTNodes - bool inClassTypeDef; - /* ---- Visit AST ---- */ atl::shared_ptr visit(AddressOf &ao) override; atl::shared_ptr visit(Allocation &a) override; - atl::shared_ptr visit(ArrayAccess &aa) override; atl::shared_ptr visit(ArrayType &at) override; atl::shared_ptr visit(Assign &as) override; atl::shared_ptr visit(BaseType &bt) override; @@ -43,6 +39,7 @@ class SemanticAnalysis : public ASTVisitor> { atl::shared_ptr visit(ClassType &ct) override; atl::shared_ptr visit(ClassTypeDecl &ctd) override; atl::shared_ptr visit(ClassTypeDef &ctd) override; + atl::shared_ptr visit(ConstructorCall &cc) override; atl::shared_ptr visit(ConstructorDecl &cd) override; atl::shared_ptr visit(ConstructorDef &cd) override; atl::shared_ptr visit(Deletion &d) override; @@ -69,6 +66,7 @@ class SemanticAnalysis : public ASTVisitor> { atl::shared_ptr visit(Return &r) override; atl::shared_ptr visit(SizeOf &so) override; atl::shared_ptr visit(StringLiteral &sl) override; + atl::shared_ptr visit(SubscriptOp &so) override; atl::shared_ptr visit(TertiaryExpr &t) override; atl::shared_ptr visit(Throw &t) override; atl::shared_ptr visit(TypeCast &tc) override; @@ -78,6 +76,10 @@ class SemanticAnalysis : public ASTVisitor> { atl::shared_ptr visit(VarDef &vd) override; atl::shared_ptr visit(VarExpr &ve) override; atl::shared_ptr visit(While &w) override; + + /* Helpers */ + atl::shared_ptr collapseReferenceTypes(atl::shared_ptr type); + // TODO: ~Create: Type preventCascade(const Type t); }; } // namespace ACC diff --git a/include/passes/SourceOutput.h b/include/passes/SourceOutput.h index b4be0b7..26a5e4d 100644 --- a/include/passes/SourceOutput.h +++ b/include/passes/SourceOutput.h @@ -27,7 +27,6 @@ class SourceOutput : public ASTVisitor { atl::string visit(AddressOf &ao) override; atl::string visit(Allocation &a) override; - atl::string visit(ArrayAccess &aa) override; atl::string visit(ArrayType &at) override; atl::string visit(Assign &as) override; atl::string visit(BaseType &bt) override; @@ -38,6 +37,7 @@ class SourceOutput : public ASTVisitor { atl::string visit(ClassType &ct) override; atl::string visit(ClassTypeDecl &ctd) override; atl::string visit(ClassTypeDef &ctd) override; + atl::string visit(ConstructorCall &cc) override; atl::string visit(ConstructorDecl &cd) override; atl::string visit(ConstructorDef &cd) override; atl::string visit(Deletion &d) override; @@ -64,6 +64,7 @@ class SourceOutput : public ASTVisitor { atl::string visit(Return &r) override; atl::string visit(SizeOf &so) override; atl::string visit(StringLiteral &sl) override; + atl::string visit(SubscriptOp &so) override; atl::string visit(TertiaryExpr &t) override; atl::string visit(Throw &t) override; atl::string visit(TypeCast &tc) override; diff --git a/include/targets/GenerateX86.h b/include/targets/GenerateX86.h index a9815fc..09b2ab1 100644 --- a/include/targets/GenerateX86.h +++ b/include/targets/GenerateX86.h @@ -26,7 +26,7 @@ class GenerateX86 : public ASTVisitor> { X86::Writer x86; atl::shared_ptr progAST; - atl::shared_ptr currScope; + atl::shared_ptr currScope; int blockCount = 0; int currFpOffset = 0; @@ -38,7 +38,6 @@ class GenerateX86 : public ASTVisitor> { atl::shared_ptr visit(AddressOf &ao) override; atl::shared_ptr visit(Allocation &a) override; - atl::shared_ptr visit(ArrayAccess &aa) override; atl::shared_ptr visit(ArrayType &at) override; atl::shared_ptr visit(Assign &as) override; atl::shared_ptr visit(BaseType &bt) override; @@ -49,6 +48,7 @@ class GenerateX86 : public ASTVisitor> { atl::shared_ptr visit(ClassType &ct) override; atl::shared_ptr visit(ClassTypeDecl &ctd) override; atl::shared_ptr visit(ClassTypeDef &ctd) override; + atl::shared_ptr visit(ConstructorCall &cc) override; atl::shared_ptr visit(ConstructorDecl &cd) override; atl::shared_ptr visit(ConstructorDef &cd) override; atl::shared_ptr visit(Deletion &d) override; @@ -75,6 +75,7 @@ class GenerateX86 : public ASTVisitor> { atl::shared_ptr visit(Return &r) override; atl::shared_ptr visit(SizeOf &so) override; atl::shared_ptr visit(StringLiteral &sl) override; + atl::shared_ptr visit(SubscriptOp &so) override; atl::shared_ptr visit(TertiaryExpr &t) override; atl::shared_ptr visit(Throw &t) override; atl::shared_ptr visit(TypeCast &tc) override; diff --git a/src/Lexer.cpp b/src/Lexer.cpp index 8f99a6f..1bc3bf6 100644 --- a/src/Lexer.cpp +++ b/src/Lexer.cpp @@ -387,14 +387,10 @@ SourceToken Lexer::nextToken() { // Recognise INT_LITERAL Token. if (atl::isdigit(c)) { atl::string literal(1, c); - if (scanner.peek() == 'x') { + while (atl::isdigit(scanner.peek())) + literal += scanner.next(); + if (scanner.peek() == 'u') literal += scanner.next(); - while (atl::isalpha(scanner.peek()) || atl::isdigit(scanner.peek())) - literal += scanner.next(); - } else { - while (atl::isdigit(scanner.peek())) - literal += scanner.next(); - } return SourceToken(TC::INT_LITERAL, scanner.getPosition(), literal); } diff --git a/src/Parser.cpp b/src/Parser.cpp index 202464d..ae24839 100644 --- a/src/Parser.cpp +++ b/src/Parser.cpp @@ -326,7 +326,9 @@ atl::shared_ptr Parser::parseIdentifier() { new Identifier(parseOperatorOverload()))); break; } - identifier = parseIdentifier(); + const atl::string identData = expect(TC::IDENTIFIER).data; + identifier = + createNode(new Identifier(identData, identifier)); } } return identifier; @@ -494,7 +496,7 @@ atl::shared_ptr Parser::parseDeletion() { const atl::shared_ptr deletionVar = parseObjExpr(); return createNode( - atl::make_shared(Deletion(deletionType, deletionVar))); + atl::shared_ptr(new Deletion(deletionType, deletionVar))); } atl::shared_ptr Parser::parseDestructor() { expect(TC::DESTRUCTOR); @@ -541,8 +543,8 @@ atl::shared_ptr Parser::parseEnumClassTypeDecl() { moreStates = false; } while (moreStates); expect(TC::RBRA); - return createNode(atl::make_shared( - EnumClassTypeDecl(enumIdentifier, states))); + return createNode(atl::shared_ptr( + new EnumClassTypeDecl(enumIdentifier, states))); } atl::shared_ptr Parser::parseFunDecl() { atl::set funModifiers; @@ -581,7 +583,6 @@ atl::shared_ptr Parser::parseFunDecl() { expect(TC::CONST); funModifiers.insert(FunDecl::FunModifiers::CONST); } - // TODO: Modifiers for FunDecls if (acceptBlock() && !isDef) { throw ACC::Error( @@ -602,7 +603,7 @@ atl::shared_ptr Parser::parseTypeDefDecl() { atl::shared_ptr aliasedType = parseType(); const atl::shared_ptr typeAlias = parseIdentifier(); return createNode( - atl::make_shared(TypeDefDecl(aliasedType, typeAlias))); + atl::shared_ptr(new TypeDefDecl(aliasedType, typeAlias))); } atl::shared_ptr Parser::parseVarDecl() { if (accept(TC::STATIC)) @@ -642,8 +643,8 @@ atl::shared_ptr Parser::parseVarDecl() { params.push_back(parseLitExpr()); } expect(TC::RPAR); - const atl::shared_ptr constructorCall( - new FunCall(classType->identifier, params)); + const atl::shared_ptr constructorCall( + new ConstructorCall(classType->identifier, params)); atl::shared_ptr output( new VarDef(varType, varIdentifier, constructorCall)); output->Decl::position = prevPosition; @@ -666,7 +667,7 @@ atl::shared_ptr Parser::parseType() { if (acceptClassType()) { const atl::shared_ptr classIdentifier = parseIdentifier(); type = createNode( - atl::make_shared(ClassType(classIdentifier))); + atl::shared_ptr(new ClassType(classIdentifier))); } else { const TC baseType = expect({TC::INT, TC::CHAR, TC::VOID, TC::SHORT, TC::UINT, TC::BOOL}) @@ -723,7 +724,7 @@ atl::shared_ptr Parser::parseAssign() { atl::shared_ptr lhs = parseExpr(); expect(TC::ASSIGN); atl::shared_ptr rhs = parseExpr(); - return createNode(atl::make_shared(Assign(lhs, rhs))); + return createNode(atl::shared_ptr(new Assign(lhs, rhs))); } atl::shared_ptr Parser::parseBlock() { expect(TC::LBRA); @@ -735,7 +736,7 @@ atl::shared_ptr Parser::parseBlock() { } expect(TC::RBRA); - return createNode(atl::make_shared(Block(blockStmts))); + return createNode(atl::shared_ptr(new Block(blockStmts))); } atl::shared_ptr Parser::parseDoWhile() { expect(TC::DO); @@ -747,7 +748,7 @@ atl::shared_ptr Parser::parseDoWhile() { expect(TC::SC); return createNode( - atl::make_shared(DoWhile(whileBody, whileCondition))); + atl::shared_ptr(new DoWhile(whileBody, whileCondition))); } atl::shared_ptr Parser::parseFor() { expect(TC::FOR); @@ -757,7 +758,6 @@ atl::shared_ptr Parser::parseFor() { const atl::shared_ptr condition = parseExpr(); expect(TC::SC); const atl::shared_ptr endBodyExpr = parseExpr(); - /* TODO: Check this Stmt is Valid ASTNode Type. */ if (endBodyExpr->astClass() != "PrefixOp") throw ACC::Error("Parser TEMP: For Loops do not support end of body " "expressions other than " @@ -765,8 +765,8 @@ atl::shared_ptr Parser::parseFor() { currToken.position); expect(TC::RPAR); const atl::shared_ptr body = parseStmt(); - return createNode( - atl::make_shared(For(initialVarDecl, condition, endBodyExpr, body))); + return createNode(atl::shared_ptr( + new For(initialVarDecl, condition, endBodyExpr, body))); } atl::shared_ptr Parser::parseIf() { expect(TC::IF); @@ -778,9 +778,9 @@ atl::shared_ptr Parser::parseIf() { expect(TC::ELSE); atl::shared_ptr elseBody = parseStmt(); return createNode( - atl::make_shared(If(ifCondition, ifBody, elseBody))); + atl::shared_ptr(new If(ifCondition, ifBody, elseBody))); } else { - return createNode(atl::make_shared(If(ifCondition, ifBody))); + return createNode(atl::shared_ptr(new If(ifCondition, ifBody))); } } atl::shared_ptr Parser::parseNamespace() { @@ -797,18 +797,18 @@ atl::shared_ptr Parser::parseNamespace() { namespaceDecls.push_back(parseNamespace()); } expect(TC::RBRA); - return createNode( - atl::make_shared(Namespace(namespaceIdent, namespaceDecls))); + return createNode(atl::shared_ptr( + new Namespace(namespaceIdent, namespaceDecls))); } atl::shared_ptr Parser::parseReturn() { expect(TC::RETURN); if (acceptExpr()) { atl::shared_ptr returnExpr = parseExpr(); expect(TC::SC); - return createNode(atl::make_shared(Return(returnExpr))); + return createNode(atl::shared_ptr(new Return(returnExpr))); } else { expect(TC::SC); - return createNode(atl::make_shared(Return())); + return createNode(atl::shared_ptr(new Return())); } } atl::shared_ptr Parser::parseStmt() { @@ -851,7 +851,7 @@ atl::shared_ptr Parser::parseStmt() { expect(TC::ASSIGN); atl::shared_ptr rhs = parseExpr(); expect(TC::SC); - return createNode(atl::make_shared(Assign(expr, rhs))); + return createNode(atl::shared_ptr(new Assign(expr, rhs))); } expect(TC::SC); @@ -861,8 +861,8 @@ atl::shared_ptr Parser::parseThrow() { expect(TC::THROW); const atl::string stringLiteral = expect(TC::STRING_LITERAL).data; expect(TC::SC); - return createNode(atl::make_shared( - Throw(atl::make_shared(StringLiteral(stringLiteral))))); + return createNode(atl::shared_ptr(new Throw( + atl::shared_ptr(new StringLiteral(stringLiteral))))); } atl::shared_ptr Parser::parseWhile() { expect(TC::WHILE); @@ -872,7 +872,7 @@ atl::shared_ptr Parser::parseWhile() { atl::shared_ptr whileBody = parseStmt(); return createNode( - atl::make_shared(While(whileBody, whileCondition))); + atl::shared_ptr(new While(whileBody, whileCondition))); } /* -- Exprs -- */ @@ -885,14 +885,15 @@ atl::shared_ptr Parser::parseExpr() { const atl::shared_ptr tertiaryIfBody = parseBoolExpr(); expect(TC::COLON); const atl::shared_ptr tertiaryElseBody = parseBoolExpr(); - output = createNode(atl::make_shared( - TertiaryExpr(tertiaryCondition, tertiaryIfBody, tertiaryElseBody))); + output = createNode( + atl::shared_ptr(new TertiaryExpr( + tertiaryCondition, tertiaryIfBody, tertiaryElseBody))); } else { const atl::shared_ptr &lhs = output; expect(TC::ASSIGNADD); const atl::shared_ptr rhs = parseBoolExpr(); output = createNode( - atl::make_shared(BinOp(lhs, Op::ASSIGNADD, rhs))); + atl::shared_ptr(new BinOp(lhs, Op::ASSIGNADD, rhs))); } } return output; @@ -904,13 +905,14 @@ atl::shared_ptr Parser::parseBoolExpr() { if (accept(TC::AND)) { expect(TC::AND); rhs = parseEqualExpr(); - lhs = - createNode(atl::make_shared(BinOp(lhs, Op::AND, rhs))); + lhs = createNode( + atl::shared_ptr(new BinOp(lhs, Op::AND, rhs))); } if (accept(TC::OR)) { expect(TC::OR); rhs = parseEqualExpr(); - lhs = createNode(atl::make_shared(BinOp(lhs, Op::OR, rhs))); + lhs = createNode( + atl::shared_ptr(new BinOp(lhs, Op::OR, rhs))); } } return lhs; @@ -922,12 +924,14 @@ atl::shared_ptr Parser::parseEqualExpr() { if (accept(TC::EQ)) { expect(TC::EQ); rhs = parseCompExpr(); - lhs = createNode(atl::make_shared(BinOp(lhs, Op::EQ, rhs))); + lhs = createNode( + atl::shared_ptr(new BinOp(lhs, Op::EQ, rhs))); } if (accept(TC::NE)) { expect(TC::NE); rhs = parseCompExpr(); - lhs = createNode(atl::make_shared(BinOp(lhs, Op::NE, rhs))); + lhs = createNode( + atl::shared_ptr(new BinOp(lhs, Op::NE, rhs))); } } return lhs; @@ -939,22 +943,26 @@ atl::shared_ptr Parser::parseCompExpr() { if (accept(TC::LE)) { expect(TC::LE); rhs = parseAddExpr(); - lhs = createNode(atl::make_shared(BinOp(lhs, Op::LE, rhs))); + lhs = createNode( + atl::shared_ptr(new BinOp(lhs, Op::LE, rhs))); } if (accept(TC::LT)) { expect(TC::LT); rhs = parseAddExpr(); - lhs = createNode(atl::make_shared(BinOp(lhs, Op::LT, rhs))); + lhs = createNode( + atl::shared_ptr(new BinOp(lhs, Op::LT, rhs))); } if (accept(TC::GE)) { expect(TC::GE); rhs = parseAddExpr(); - lhs = createNode(atl::make_shared(BinOp(lhs, Op::GE, rhs))); + lhs = createNode( + atl::shared_ptr(new BinOp(lhs, Op::GE, rhs))); } if (accept(TC::GT)) { expect(TC::GT); rhs = parseAddExpr(); - lhs = createNode(atl::make_shared(BinOp(lhs, Op::GT, rhs))); + lhs = createNode( + atl::shared_ptr(new BinOp(lhs, Op::GT, rhs))); } } return lhs; @@ -966,14 +974,14 @@ atl::shared_ptr Parser::parseAddExpr() { if (accept(TC::MINUS)) { expect(TC::MINUS); rhs = parseMulExpr(); - lhs = - createNode(atl::make_shared(BinOp(lhs, Op::SUB, rhs))); + lhs = createNode( + atl::shared_ptr(new BinOp(lhs, Op::SUB, rhs))); } if (accept(TC::PLUS)) { expect(TC::PLUS); rhs = parseMulExpr(); - lhs = - createNode(atl::make_shared(BinOp(lhs, Op::ADD, rhs))); + lhs = createNode( + atl::shared_ptr(new BinOp(lhs, Op::ADD, rhs))); } } return lhs; @@ -985,20 +993,20 @@ atl::shared_ptr Parser::parseMulExpr() { if (accept(TC::ASTERIX)) { expect(TC::ASTERIX); rhs = parseUnaryExpr(); - lhs = - createNode(atl::make_shared(BinOp(lhs, Op::MUL, rhs))); + lhs = createNode( + atl::shared_ptr(new BinOp(lhs, Op::MUL, rhs))); } if (accept(TC::DIV)) { expect(TC::DIV); rhs = parseUnaryExpr(); - lhs = - createNode(atl::make_shared(BinOp(lhs, Op::DIV, rhs))); + lhs = createNode( + atl::shared_ptr(new BinOp(lhs, Op::DIV, rhs))); } if (accept(TC::REM)) { expect(TC::REM); rhs = parseUnaryExpr(); - lhs = - createNode(atl::make_shared(BinOp(lhs, Op::MOD, rhs))); + lhs = createNode( + atl::shared_ptr(new BinOp(lhs, Op::MOD, rhs))); } } return lhs; @@ -1009,12 +1017,12 @@ atl::shared_ptr Parser::parseUnaryExpr() { expect(TC::LPAR); atl::shared_ptr type = parseType(); expect(TC::RPAR); - return createNode(atl::make_shared(SizeOf(type))); + return createNode(atl::shared_ptr(new SizeOf(type))); } if (accept(TC::ASTERIX)) { expect(TC::ASTERIX); atl::shared_ptr rhs = parseObjExpr(); - return createNode(atl::make_shared(ValueAt(rhs))); + return createNode(atl::shared_ptr(new ValueAt(rhs))); } if (accept(TC::LPAR) && (acceptType(1) && !accept(TC::IDENTIFIER, 1))) { expect(TC::LPAR); @@ -1022,13 +1030,14 @@ atl::shared_ptr Parser::parseUnaryExpr() { expect(TC::RPAR); atl::shared_ptr expToCast = parseObjExpr(); return createNode( - atl::make_shared(TypeCast(castType, expToCast))); + atl::shared_ptr(new TypeCast(castType, expToCast))); } if (accept(TC::MINUS)) { expect(TC::MINUS); atl::shared_ptr lhs(new IntLiteral("0")); atl::shared_ptr rhs = parseObjExpr(); - return createNode(atl::make_shared(BinOp(lhs, Op::SUB, rhs))); + return createNode( + atl::shared_ptr(new BinOp(lhs, Op::SUB, rhs))); } if (accept({TC::PREFIXINC, TC::PREFIXDEC})) { TC operatorToken = expect({TC::PREFIXINC, TC::PREFIXDEC}).tokenClass; @@ -1045,18 +1054,17 @@ atl::shared_ptr Parser::parseUnaryExpr() { const atl::shared_ptr variable = atl::static_pointer_cast(incrementExpr); return createNode( - atl::make_shared(PrefixOp(operation, variable))); + atl::shared_ptr(new PrefixOp(operation, variable))); } if (accept(TC::NEW)) { - /* TODO: Parse Heap Allocation. */ expect(TC::NEW); /* Constructor Call */ if (accept(TC::IDENTIFIER) && accept(TC::LPAR, 1)) { atl::shared_ptr funCall = parseObjExpr(); if (funCall->astClass() != "FunCall") throw ACC::Error("Parser: Expected FunCall", currToken.position); - return createNode(atl::make_shared( - Allocation(atl::static_pointer_cast(funCall)))); + return createNode(atl::shared_ptr( + new Allocation(atl::static_pointer_cast(funCall)))); } else { atl::shared_ptr allocatedType = parseType(); if (accept(TC::LSBR)) { @@ -1066,7 +1074,7 @@ atl::shared_ptr Parser::parseUnaryExpr() { allocatedType = atl::shared_ptr(new ArrayType(allocatedType, arraySize)); return createNode( - atl::make_shared(Allocation(allocatedType))); + atl::shared_ptr(new Allocation(allocatedType))); } } } @@ -1074,14 +1082,20 @@ atl::shared_ptr Parser::parseUnaryExpr() { expect(TC::REF); const atl::shared_ptr addrOfExpr = parseObjExpr(); return createNode( - atl::make_shared(AddressOf(addrOfExpr))); + atl::shared_ptr(new AddressOf(addrOfExpr))); } if (accept(TC::NOT)) { expect(TC::NOT); // Parse NOT Node. } - return parseObjExpr(); + atl::shared_ptr objExpr = parseObjExpr(); + + if (accept(TC::LSBR)) { + expect(TC::LSBR); + } + + return objExpr; } atl::shared_ptr Parser::parseObjExpr() { if (accept(TC::IDENTIFIER)) { @@ -1099,9 +1113,10 @@ atl::shared_ptr Parser::parseObjExpr() { expect(TC::RPAR); objExpr = createNode( - atl::make_shared(FunCall(ident, params))); + atl::shared_ptr(new FunCall(ident, params))); } else { - objExpr = createNode(atl::make_shared(VarExpr(ident))); + objExpr = + createNode(atl::shared_ptr(new VarExpr(ident))); } while (accept({TC::DOT, TC::PTRDOT, TC::LSBR})) { @@ -1110,21 +1125,21 @@ atl::shared_ptr Parser::parseObjExpr() { expect({TC::DOT, TC::PTRDOT}).tokenClass; if (accept(TC::LPAR, 1)) { atl::shared_ptr memberFunCall = parseFunCall(); - objExpr = createNode(atl::make_shared( - MemberCall(objExpr, memberFunCall, accessType))); + objExpr = createNode(atl::shared_ptr( + new MemberCall(objExpr, memberFunCall, accessType))); } else { const atl::shared_ptr fieldIdentifier = parseIdentifier(); const atl::shared_ptr fieldVarExpr = createNode( atl::shared_ptr(new VarExpr(fieldIdentifier))); - objExpr = createNode(atl::make_shared( - MemberAccess(objExpr, fieldVarExpr, accessType))); + objExpr = createNode(atl::shared_ptr( + new MemberAccess(objExpr, fieldVarExpr, accessType))); } } else { expect(TC::LSBR); - atl::shared_ptr arrayIndexExpr = parseObjExpr(); + atl::shared_ptr indexExpr = parseObjExpr(); expect(TC::RSBR); - objExpr = createNode(atl::make_shared( - ArrayAccess(objExpr, arrayIndexExpr))); + objExpr = createNode( + atl::shared_ptr(new SubscriptOp(objExpr, indexExpr))); } } return objExpr; @@ -1132,7 +1147,7 @@ atl::shared_ptr Parser::parseObjExpr() { if (accept(TC::THIS)) { expect(TC::THIS); atl::shared_ptr output = createNode( - atl::make_shared(VarExpr(createNode( + atl::shared_ptr(new VarExpr(createNode( atl::shared_ptr(new Identifier("this")))))); while (accept({TC::DOT, TC::PTRDOT, TC::LSBR})) { if (accept({TC::DOT, TC::PTRDOT})) { @@ -1140,21 +1155,21 @@ atl::shared_ptr Parser::parseObjExpr() { expect({TC::DOT, TC::PTRDOT}).tokenClass; if (accept(TC::LPAR, 1)) { atl::shared_ptr memberFunCall = parseFunCall(); - output = createNode(atl::make_shared( - MemberCall(output, memberFunCall, accessType))); + output = createNode(atl::shared_ptr( + new MemberCall(output, memberFunCall, accessType))); } else { const atl::shared_ptr fieldIdentifier = parseIdentifier(); const atl::shared_ptr fieldVarExpr = createNode( atl::shared_ptr(new VarExpr(fieldIdentifier))); - output = createNode(atl::make_shared( - MemberAccess(output, fieldVarExpr, accessType))); + output = createNode(atl::shared_ptr( + new MemberAccess(output, fieldVarExpr, accessType))); } } else { expect(TC::LSBR); - atl::shared_ptr arrayIndexExpr = parseObjExpr(); + atl::shared_ptr indexExpr = parseObjExpr(); expect(TC::RSBR); - output = createNode( - atl::make_shared(ArrayAccess(output, arrayIndexExpr))); + output = createNode( + atl::shared_ptr(new SubscriptOp(output, indexExpr))); } } return output; @@ -1167,21 +1182,21 @@ atl::shared_ptr Parser::parseObjExpr() { expect({TC::DOT, TC::PTRDOT}).tokenClass; if (accept(TC::LPAR, 1)) { atl::shared_ptr memberFunCall = parseFunCall(); - output = createNode(atl::make_shared( - MemberCall(output, memberFunCall, accessType))); + output = createNode(atl::shared_ptr( + new MemberCall(output, memberFunCall, accessType))); } else { const atl::shared_ptr fieldIdentifier = parseIdentifier(); const atl::shared_ptr fieldVarExpr = createNode( atl::shared_ptr(new VarExpr(fieldIdentifier))); - output = createNode(atl::make_shared( - MemberAccess(output, fieldVarExpr, accessType))); + output = createNode(atl::shared_ptr( + new MemberAccess(output, fieldVarExpr, accessType))); } } else { expect(TC::LSBR); - atl::shared_ptr arrayIndexExpr = parseObjExpr(); + atl::shared_ptr indexExpr = parseObjExpr(); expect(TC::RSBR); - output = createNode( - atl::make_shared(ArrayAccess(output, arrayIndexExpr))); + output = createNode( + atl::shared_ptr(new SubscriptOp(output, indexExpr))); } } return output; @@ -1198,41 +1213,42 @@ atl::shared_ptr Parser::parseFunCall() { } expect(TC::RPAR); - return createNode(atl::make_shared(FunCall(ident, params))); + return createNode( + atl::shared_ptr(new FunCall(ident, params))); } atl::shared_ptr Parser::parseLitExpr() { if (accept(TC::INT_LITERAL)) { - return createNode( - atl::make_shared(IntLiteral(expect(TC::INT_LITERAL).data))); + return createNode(atl::shared_ptr( + new IntLiteral(expect(TC::INT_LITERAL).data))); } if (accept(TC::CHAR_LITERAL)) { - return createNode(atl::make_shared( - CharLiteral(expect(TC::CHAR_LITERAL).data))); + return createNode(atl::shared_ptr( + new CharLiteral(expect(TC::CHAR_LITERAL).data))); } if (accept(TC::STRING_LITERAL)) { - return createNode(atl::make_shared( - StringLiteral(expect(TC::STRING_LITERAL).data))); + return createNode(atl::shared_ptr( + new StringLiteral(expect(TC::STRING_LITERAL).data))); } if (accept(TC::TRUE_VAL)) { expect(TC::TRUE_VAL); return createNode( - atl::make_shared(BoolLiteral("true"))); + atl::shared_ptr(new BoolLiteral("true"))); } if (accept(TC::FALSE_VAL)) { expect(TC::FALSE_VAL); return createNode( - atl::make_shared(BoolLiteral("false"))); + atl::shared_ptr(new BoolLiteral("false"))); } if (accept(TC::NULLPTR)) { expect(TC::NULLPTR); - return createNode(atl::make_shared(Nullptr())); + return createNode(atl::shared_ptr(new Nullptr())); } if (accept(TC::LPAR) && (!acceptType(1) || accept(TC::IDENTIFIER, 1))) { expect(TC::LPAR); atl::shared_ptr innerExpr = parseExpr(); expect(TC::RPAR); return createNode( - atl::make_shared(ParenthExpr(innerExpr))); + atl::shared_ptr(new ParenthExpr(innerExpr))); } if (acceptExpr()) return parseExpr(); @@ -1262,19 +1278,19 @@ atl::shared_ptr Parser::tokenToType(const TC &tc) { switch (tc) { case TC::INT: return createNode( - atl::make_shared(BaseType(PrimitiveType::INT))); + atl::shared_ptr(new BaseType(PrimitiveType::INT))); case TC::CHAR: return createNode( - atl::make_shared(BaseType(PrimitiveType::CHAR))); + atl::shared_ptr(new BaseType(PrimitiveType::CHAR))); case TC::SHORT: return createNode( - atl::make_shared(BaseType(PrimitiveType::SHORT))); + atl::shared_ptr(new BaseType(PrimitiveType::SHORT))); case TC::VOID: return createNode( - atl::make_shared(BaseType(PrimitiveType::VOID))); + atl::shared_ptr(new BaseType(PrimitiveType::VOID))); case TC::BOOL: return createNode( - atl::make_shared(BaseType(PrimitiveType::BOOL))); + atl::shared_ptr(new BaseType(PrimitiveType::BOOL))); default: throw ACC::Error("Parser: Cannot resolve Token " + tokToStr(tc) + " to a type.", diff --git a/src/ast/AddressOf.cpp b/src/ast/AddressOf.cpp index 3aeced5..541f605 100644 --- a/src/ast/AddressOf.cpp +++ b/src/ast/AddressOf.cpp @@ -5,10 +5,6 @@ using namespace ACC; AddressOf::AddressOf(const atl::shared_ptr &p_addressOfExpr) : addressOfExpr(p_addressOfExpr) {} -atl::string AddressOf::getSignature() const { - return addressOfExpr->getSignature() + "*"; -} - bool AddressOf::operator==(Expr &rhs) const { if (rhs.astClass() == astClass()) return *this == *static_cast(&rhs); diff --git a/src/ast/Allocation.cpp b/src/ast/Allocation.cpp index df78c8f..7978949 100644 --- a/src/ast/Allocation.cpp +++ b/src/ast/Allocation.cpp @@ -8,13 +8,6 @@ Allocation::Allocation(const atl::shared_ptr &p_varType) Allocation::Allocation(const atl::shared_ptr &p_varConstructorCall) : varType(nullptr), varConstructorCall(p_varConstructorCall) {} -atl::string Allocation::getSignature() const { - if (varType != nullptr) - return varType->getSignature() + "*"; - - return varConstructorCall->getSignature() + "*"; -} - bool Allocation::operator==(Expr &rhs) const { if (rhs.astClass() == astClass()) return *this == *static_cast(&rhs); diff --git a/src/ast/ArrayAccess.cpp b/src/ast/ArrayAccess.cpp deleted file mode 100644 index f036742..0000000 --- a/src/ast/ArrayAccess.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include "ast/ArrayAccess.h" - -using namespace ACC; - -ArrayAccess::ArrayAccess(const atl::shared_ptr &p_array, - const atl::shared_ptr &p_index) - : array(p_array), index(p_index) {} - -atl::string ArrayAccess::getSignature() const { return array->getSignature(); } - -bool ArrayAccess::operator==(Expr &rhs) const { - if (rhs.astClass() == astClass()) - return *this == *static_cast(&rhs); - return false; -} - -bool ArrayAccess::operator!=(Expr &rhs) const { return !(*this == rhs); } - -bool ArrayAccess::operator==(const ArrayAccess &rhs) const { - if (*array != *rhs.array) - return false; - - if (index != rhs.index) - return false; - - return true; -} - -bool ArrayAccess::operator!=(const ArrayAccess &rhs) const { - return !(*this == rhs); -} \ No newline at end of file diff --git a/src/ast/ArrayType.cpp b/src/ast/ArrayType.cpp index d4eb347..5709d29 100644 --- a/src/ast/ArrayType.cpp +++ b/src/ast/ArrayType.cpp @@ -10,8 +10,8 @@ ArrayType::ArrayType(const atl::shared_ptr &p_type, const atl::shared_ptr &p_size) : PointerType(p_type), size(p_size) {} -int ArrayType::getBytes() const { - int elementSize = pointedType->getBytes(); +unsigned int ArrayType::getBytes() const { + unsigned int elementSize = pointedType->getBytes(); if (size->astClass() != "IntLiteral") throw ACC::Error( "Internal Error: Attempted to getBytes() of dynamic ArrayType."); @@ -21,10 +21,6 @@ int ArrayType::getBytes() const { return atl::stoi(sizeIntLiteral->getLiteral()) * elementSize; } -atl::string ArrayType::getSignature() const { - return pointedType->getSignature() + "[]"; -} - bool ArrayType::operator==(Type &rhs) const { if (rhs.astClass() == "PointerType") { const PointerType &pt = *static_cast(&rhs); diff --git a/src/ast/BaseType.cpp b/src/ast/BaseType.cpp index 8e45a53..35a4bbf 100644 --- a/src/ast/BaseType.cpp +++ b/src/ast/BaseType.cpp @@ -5,7 +5,7 @@ using namespace ACC; BaseType::BaseType(PrimitiveType p_pType) : primitiveType(p_pType) {} -int BaseType::getBytes() const { +unsigned int BaseType::getBytes() const { switch (primitiveType) { case PrimitiveType::CHAR: return 1; @@ -26,27 +26,6 @@ int BaseType::getBytes() const { } } -atl::string BaseType::getSignature() const { - switch (primitiveType) { - case PrimitiveType::CHAR: - return "char"; - case PrimitiveType::INT: - return "int"; - case PrimitiveType::SHORT: - return "short"; - case PrimitiveType::VOID: - return "void"; - case PrimitiveType::UINT: - return "uint"; - case PrimitiveType::BOOL: - return "bool"; - case PrimitiveType::NULLPTR_T: - return "nullptr_t"; - default: - return "nullptr_t"; - } -} - bool BaseType::operator==(Type &rhs) const { if (rhs.astClass() == "ReferenceType") { const atl::shared_ptr rhsRefType( diff --git a/src/ast/BinOp.cpp b/src/ast/BinOp.cpp index 77eac25..00ee68d 100644 --- a/src/ast/BinOp.cpp +++ b/src/ast/BinOp.cpp @@ -6,41 +6,6 @@ BinOp::BinOp(const atl::shared_ptr &p_lhs, const Op p_operation, const atl::shared_ptr &p_rhs) : lhs(p_lhs), operation(p_operation), rhs(p_rhs) {} -atl::string BinOp::getSignature() const { - switch (operation) { - case Op::ADD: - return lhs->getSignature(); - case Op::SUB: - return lhs->getSignature(); - case Op::MUL: - return lhs->getSignature(); - case Op::DIV: - return lhs->getSignature(); - case Op::MOD: - return "int"; - case Op::GT: - return "bool"; - case Op::LT: - return "bool"; - case Op::GE: - return "bool"; - case Op::LE: - return "bool"; - case Op::NE: - return "bool"; - case Op::EQ: - return "bool"; - case Op::OR: - return "bool"; - case Op::AND: - return "bool"; - case Op::ASSIGNADD: - return lhs->getSignature(); - default: - return "int"; - } -} - bool BinOp::operator==(Expr &rhs) const { if (rhs.astClass() == astClass()) return *this == *static_cast(&rhs); diff --git a/src/ast/Block.cpp b/src/ast/Block.cpp index ba2ff07..a76d288 100644 --- a/src/ast/Block.cpp +++ b/src/ast/Block.cpp @@ -1,4 +1,8 @@ #include "ast/Block.h" +#include "ast/ClassType.h" +#include "ast/ClassTypeDef.h" +#include "ast/FunDef.h" +#include "ast/VarDef.h" using namespace ACC; @@ -10,7 +14,7 @@ bool Block::operator==(const Block &rhs) const { return false; for (unsigned int i = 0; i < stmts.size(); ++i) - /* @TODO Implement comparitors for Stmts. */ + /* TODO: Implement comparitors for Stmts. */ if (stmts[i]->astClass() != rhs.stmts[i]->astClass()) return false; @@ -18,3 +22,60 @@ bool Block::operator==(const Block &rhs) const { } bool Block::operator!=(const Block &rhs) const { return !(*this == rhs); } + +atl::shared_ptr +Block::findClassDecl(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl) const { + return outerScope->findClassDecl(identifier, exemptDecl); +} + +atl::shared_ptr +Block::findClassDef(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl) const { + return outerScope->findClassDef(identifier, exemptDecl); +} + +atl::shared_ptr +Block::findFunDecl(const FunSignature &funSignature, + const atl::shared_ptr &exemptDecl) const { + return outerScope->findFunDecl(funSignature, exemptDecl); +} + +atl::shared_ptr +Block::findFunDeclLocal(const FunSignature &funSignature, + const atl::shared_ptr &exemptDecl) const { + return nullptr; +} + +atl::shared_ptr +Block::findVarDecl(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl) const { + const atl::shared_ptr localFind = + findVarDeclLocal(identifier, exemptDecl); + if (localFind != nullptr) + return localFind; + else if (outerScope != nullptr) + return outerScope->findVarDecl(identifier, exemptDecl); + else + return nullptr; +} + +atl::shared_ptr +Block::findVarDeclLocal(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl) const { + for (int idx = stmtsChecked - 1; idx >= 0; --idx) { + const atl::shared_ptr currStmt = stmts[idx]; + if (currStmt->astClass() != "VarDecl" && currStmt->astClass() != "VarDef") + continue; + const atl::shared_ptr currVarDecl = + atl::static_pointer_cast(currStmt); + if (currVarDecl.get() == exemptDecl.get()) + continue; + if (*currVarDecl->getIdentifier() != *identifier) + continue; + + return currVarDecl; + } + + return nullptr; +} \ No newline at end of file diff --git a/src/ast/BoolLiteral.cpp b/src/ast/BoolLiteral.cpp index 73d085d..e8c13f6 100644 --- a/src/ast/BoolLiteral.cpp +++ b/src/ast/BoolLiteral.cpp @@ -4,8 +4,6 @@ using namespace ACC; BoolLiteral::BoolLiteral(const atl::string &p_literal) : Literal(p_literal) {} -atl::string BoolLiteral::getSignature() const { return "bool"; } - bool BoolLiteral::operator==(Expr &rhs) const { if (rhs.astClass() == astClass()) return *this == *static_cast(&rhs); diff --git a/src/ast/CharLiteral.cpp b/src/ast/CharLiteral.cpp index c9ba189..85c604a 100644 --- a/src/ast/CharLiteral.cpp +++ b/src/ast/CharLiteral.cpp @@ -4,10 +4,6 @@ using namespace ACC; CharLiteral::CharLiteral(const atl::string &p_literal) : Literal(p_literal) {} -atl::string CharLiteral::getSignature() const { - return "char"; -} - bool CharLiteral::operator==(Expr &rhs) const { if (rhs.astClass() == astClass()) return *this == *static_cast(&rhs); diff --git a/src/ast/ClassType.cpp b/src/ast/ClassType.cpp index aa6e3a9..0a6227d 100644 --- a/src/ast/ClassType.cpp +++ b/src/ast/ClassType.cpp @@ -7,15 +7,13 @@ using namespace ACC; ClassType::ClassType(const atl::shared_ptr &p_identifier) : identifier(p_identifier) {} -int ClassType::getBytes() const { - int aggregateBytes = 0; - if (typeDefinition == nullptr) - return aggregateBytes; +unsigned int ClassType::getBytes() const { + unsigned int aggregateBytes = 0; - // @TODO: Calculate SUM of VarDecls. const unsigned int classDeclsSize = typeDefinition->classDecls.size(); for (unsigned int i = 0; i < classDeclsSize; ++i) { - if (typeDefinition->classDecls[i]->astClass() == "VarDecl") { + if (typeDefinition->classDecls[i]->astClass() == "VarDecl" || + typeDefinition->classDecls[i]->astClass() == "VarDef") { aggregateBytes += atl::static_pointer_cast(typeDefinition->classDecls[i]) ->getBytes(); @@ -25,8 +23,6 @@ int ClassType::getBytes() const { return aggregateBytes; } -atl::string ClassType::getSignature() const { return identifier->toString(); } - bool ClassType::operator==(Type &rhs) const { if (rhs.astClass() == "ReferenceType") { const atl::shared_ptr rhsRefType( diff --git a/src/ast/ClassTypeDecl.cpp b/src/ast/ClassTypeDecl.cpp index b0f5f81..9003777 100644 --- a/src/ast/ClassTypeDecl.cpp +++ b/src/ast/ClassTypeDecl.cpp @@ -1,6 +1,7 @@ -#include "ast/ClassTypeDecl.h" - #include "ast/ClassType.h" +#include "ast/ClassTypeDef.h" +#include "ast/FunDef.h" +#include "ast/VarDef.h" using namespace ACC; @@ -29,3 +30,39 @@ bool ClassTypeDecl::operator==(const ClassTypeDecl &rhs) const { bool ClassTypeDecl::operator!=(const ClassTypeDecl &rhs) const { return !(*this == rhs); } + +atl::shared_ptr +ClassTypeDecl::findClassDecl(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl) const { + return outerScope->findClassDecl(identifier, exemptDecl); +} + +atl::shared_ptr +ClassTypeDecl::findClassDef(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl) const { + return outerScope->findClassDef(identifier, exemptDecl); +} + +atl::shared_ptr +ClassTypeDecl::findFunDecl(const FunSignature &funSignature, + const atl::shared_ptr &exemptDecl) const { + return outerScope->findFunDecl(funSignature, exemptDecl); +} + +atl::shared_ptr +ClassTypeDecl::findFunDeclLocal(const FunSignature &funSignature, + const atl::shared_ptr &exemptDecl) const { + return nullptr; +} + +atl::shared_ptr +ClassTypeDecl::findVarDecl(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl) const { + return outerScope->findVarDecl(identifier, exemptDecl); +} + +atl::shared_ptr +ClassTypeDecl::findVarDeclLocal(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl) const { + return nullptr; +} \ No newline at end of file diff --git a/src/ast/ClassTypeDef.cpp b/src/ast/ClassTypeDef.cpp index 4db7522..62bd382 100644 --- a/src/ast/ClassTypeDef.cpp +++ b/src/ast/ClassTypeDef.cpp @@ -1,5 +1,5 @@ #include "ast/ClassTypeDef.h" - +#include "ast/ClassType.h" #include "ast/ConstructorDef.h" #include "ast/FunDef.h" #include "ast/PointerType.h" @@ -141,7 +141,6 @@ ClassTypeDef::ClassTypeDef( // Save to this ClassTypeDef. classDecls[declIdx] = newFunDef; } - insertDecl(currDecl); } } @@ -174,3 +173,120 @@ bool ClassTypeDef::operator==(const ClassTypeDef &rhs) const { bool ClassTypeDef::operator!=(const ClassTypeDef &rhs) const { return !(*this == rhs); } + +atl::shared_ptr +ClassTypeDef::findClassDecl(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl) const { + return outerScope->findClassDecl(identifier); +} + +atl::shared_ptr +ClassTypeDef::findClassDef(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl) const { + for (int idx = classDecls.size() - 1; idx >= 0; --idx) { + const atl::shared_ptr currDecl = classDecls[idx]; + if (currDecl->astClass() != "ClassTypeDecl" && + currDecl->astClass() != "ClassTypeDef") + continue; + if (currDecl.get() == exemptDecl.get()) + continue; + if (*currDecl->getIdentifier() != *identifier) + continue; + + return atl::static_pointer_cast(currDecl); + } + if (outerScope != nullptr) + return outerScope->findClassDecl(identifier, exemptDecl); + + return nullptr; +} + +atl::shared_ptr ClassTypeDef::findConstructorDecl( + const FunSignature &ctorSignature, + const atl::shared_ptr &exemptDecl) const { + for (int idx = classDecls.size() - 1; idx >= 0; --idx) { + const atl::shared_ptr currDecl = classDecls[idx]; + if (currDecl->astClass() != "ConstructorDecl" && + currDecl->astClass() != "ConstructorDef") + continue; + const atl::shared_ptr currCtorDecl = + atl::static_pointer_cast(currDecl); + if (currCtorDecl.get() == exemptDecl.get()) + continue; + if (ctorSignature != currCtorDecl->getSignature()) + continue; + + return currCtorDecl; + } + + return nullptr; +} + +atl::shared_ptr +ClassTypeDef::findFunDecl(const FunSignature &funSignature, + const atl::shared_ptr &exemptDecl) const { + const atl::shared_ptr localFind = + findFunDeclLocal(funSignature, exemptDecl); + if (localFind != nullptr) + return localFind; + else if (outerScope != nullptr) + return outerScope->findFunDecl(funSignature, exemptDecl); + else + return nullptr; +} + +atl::shared_ptr +ClassTypeDef::findFunDeclLocal(const FunSignature &funSignature, + const atl::shared_ptr &exemptDecl) const { + if (funSignature.namespaceCount() > 0) { + return nullptr; + } else { + /* No Namespacing on this FunSignature, search top level. */ + for (int idx = classDecls.size() - 1; idx >= 0; --idx) { + const atl::shared_ptr currDecl = classDecls[idx]; + if (currDecl->astClass() != "FunDecl" && currDecl->astClass() != "FunDef") + continue; + const atl::shared_ptr currFunDecl = + atl::static_pointer_cast(currDecl); + if (currFunDecl.get() == exemptDecl.get()) + continue; + if (funSignature != currFunDecl->getSignature()) + continue; + + return currFunDecl; + } + + return nullptr; + } +} + +atl::shared_ptr +ClassTypeDef::findVarDecl(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl) const { + const atl::shared_ptr localFind = + findVarDeclLocal(identifier, exemptDecl); + if (localFind != nullptr) + return localFind; + else if (outerScope != nullptr) + return outerScope->findVarDecl(identifier, exemptDecl); + else + return nullptr; +} + +atl::shared_ptr +ClassTypeDef::findVarDeclLocal(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl) const { + for (int idx = classDecls.size() - 1; idx >= 0; --idx) { + const atl::shared_ptr currDecl = classDecls[idx]; + if (currDecl->astClass() != "VarDecl" && currDecl->astClass() != "VarDef") + continue; + if (currDecl.get() == exemptDecl.get()) + continue; + if (*currDecl->getIdentifier() != *identifier) + continue; + + return atl::static_pointer_cast(currDecl); + } + + return nullptr; +} \ No newline at end of file diff --git a/src/ast/ConstructorCall.cpp b/src/ast/ConstructorCall.cpp new file mode 100644 index 0000000..4cc0578 --- /dev/null +++ b/src/ast/ConstructorCall.cpp @@ -0,0 +1,35 @@ +#include "ast/ConstructorCall.h" + +using namespace ACC; + +ConstructorCall::ConstructorCall( + const atl::shared_ptr &p_ctorIdentifier, + const atl::vector> &p_ctorArgs) + : constructorIdentifier(p_ctorIdentifier), constructorArgs(p_ctorArgs) {} + +bool ConstructorCall::operator==(Expr &rhs) const { + if (rhs.astClass() == astClass()) + return *this == *static_cast(&rhs); + return false; +} + +bool ConstructorCall::operator!=(Expr &rhs) const { return !(*this == rhs); } + +bool ConstructorCall::operator==(const ConstructorCall &rhs) const { + if (*constructorIdentifier != *rhs.constructorIdentifier) + return false; + + if (constructorArgs.size() != rhs.constructorArgs.size()) + return false; + + for (unsigned int i = 0; i < constructorArgs.size(); ++i) { + if (*constructorArgs[i] != *rhs.constructorArgs[i]) + return false; + } + + return true; +} + +bool ConstructorCall::operator!=(const ConstructorCall &rhs) const { + return !(*this == rhs); +} diff --git a/src/ast/ConstructorDecl.cpp b/src/ast/ConstructorDecl.cpp index cb27f6f..25c8439 100644 --- a/src/ast/ConstructorDecl.cpp +++ b/src/ast/ConstructorDecl.cpp @@ -1,4 +1,8 @@ #include "ast/ConstructorDecl.h" +#include "ast/ClassType.h" +#include "ast/ClassTypeDef.h" +#include "ast/FunDef.h" +#include "ast/VarDef.h" using namespace ACC; @@ -11,6 +15,14 @@ atl::shared_ptr ConstructorDecl::getIdentifier() const { return classType->identifier; } +const FunSignature ConstructorDecl::getSignature() const { + atl::vector> paramTypes; + for (int idx = 0; idx < constructorParams.size(); ++idx) + paramTypes.push_back(constructorParams[idx]->type); + + return FunSignature(classType, classType->identifier, paramTypes); +} + bool ConstructorDecl::operator==(Decl &rhs) const { if (rhs.astClass() == astClass()) return *this == *static_cast(&rhs); @@ -36,3 +48,39 @@ bool ConstructorDecl::operator==(const ConstructorDecl &rhs) const { bool ConstructorDecl::operator!=(const ConstructorDecl &rhs) const { return !(*this == rhs); } + +atl::shared_ptr +ConstructorDecl::findClassDecl(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl) const { + return outerScope->findClassDecl(identifier); +} + +atl::shared_ptr +ConstructorDecl::findClassDef(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl) const { + return outerScope->findClassDef(identifier); +} + +atl::shared_ptr +ConstructorDecl::findFunDecl(const FunSignature &funSignature, + const atl::shared_ptr &exemptDecl) const { + return outerScope->findFunDecl(funSignature); +} + +atl::shared_ptr ConstructorDecl::findFunDeclLocal( + const FunSignature &funSignature, + const atl::shared_ptr &exemptDecl) const { + return nullptr; +} + +atl::shared_ptr +ConstructorDecl::findVarDecl(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl) const { + return outerScope->findVarDecl(identifier); +} + +atl::shared_ptr ConstructorDecl::findVarDeclLocal( + const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl) const { + return nullptr; +} \ No newline at end of file diff --git a/src/ast/ConstructorDef.cpp b/src/ast/ConstructorDef.cpp index a6f59d6..f40979a 100644 --- a/src/ast/ConstructorDef.cpp +++ b/src/ast/ConstructorDef.cpp @@ -1,4 +1,9 @@ #include "ast/ConstructorDef.h" +#include "ast/ClassType.h" +#include "ast/ConstructorDef.h" +#include "ast/FunDef.h" +#include "ast/PointerType.h" +#include "ast/VarDecl.h" using namespace ACC; @@ -44,3 +49,56 @@ bool ConstructorDef::operator==(const ConstructorDef &rhs) const { bool ConstructorDef::operator!=(const ConstructorDef &rhs) const { return !(*this == rhs); } + +atl::shared_ptr +ConstructorDef::findClassDecl(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl) const { + return outerScope->findClassDecl(identifier, exemptDecl); +} + +atl::shared_ptr +ConstructorDef::findClassDef(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl) const { + return outerScope->findClassDef(identifier, exemptDecl); +} + +atl::shared_ptr +ConstructorDef::findFunDecl(const FunSignature &funSignature, + const atl::shared_ptr &exemptDecl) const { + return outerScope->findFunDecl(funSignature, exemptDecl); +} + +atl::shared_ptr ConstructorDef::findFunDeclLocal( + const FunSignature &funSignature, + const atl::shared_ptr &exemptDecl) const { + return nullptr; +} + +atl::shared_ptr +ConstructorDef::findVarDecl(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl) const { + const atl::shared_ptr localFind = + findVarDeclLocal(identifier, exemptDecl); + if (localFind != nullptr) + return localFind; + else if (outerScope != nullptr) + return outerScope->findVarDecl(identifier, exemptDecl); + else + return nullptr; +} + +atl::shared_ptr ConstructorDef::findVarDeclLocal( + const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl) const { + for (int idx = 0; idx < constructorParams.size(); ++idx) { + const atl::shared_ptr currParam = constructorParams[idx]; + if (currParam.get() == exemptDecl.get()) + continue; + if (*currParam->getIdentifier() != *identifier) + continue; + + return currParam; + } + + return nullptr; +} \ No newline at end of file diff --git a/src/ast/For.cpp b/src/ast/For.cpp index 470ce4a..f8b84de 100644 --- a/src/ast/For.cpp +++ b/src/ast/For.cpp @@ -1,4 +1,8 @@ #include "ast/For.h" +#include "ast/ClassType.h" +#include "ast/ClassTypeDef.h" +#include "ast/FunDef.h" +#include "ast/VarDef.h" using namespace ACC; @@ -8,3 +12,43 @@ For::For(const atl::shared_ptr &p_initialVarDecl, const atl::shared_ptr &p_body) : initialVarDecl(p_initialVarDecl), condition(p_condition), endBodyExpr(p_endBodyExpr), body(p_body) {} + +atl::shared_ptr +For::findClassDecl(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl) const { + return outerScope->findClassDecl(identifier, exemptDecl); +} + +atl::shared_ptr +For::findClassDef(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl) const { + return outerScope->findClassDef(identifier, exemptDecl); +} + +atl::shared_ptr +For::findFunDecl(const FunSignature &funSignature, + const atl::shared_ptr &exemptDecl) const { + return outerScope->findFunDecl(funSignature, exemptDecl); +} + +atl::shared_ptr +For::findFunDeclLocal(const FunSignature &funSignature, + const atl::shared_ptr &exemptDecl) const { + return nullptr; +} + +atl::shared_ptr +For::findVarDecl(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl) const { + if (initialVarDecl->identifier == identifier && + initialVarDecl.get() != exemptDecl.get()) + return initialVarDecl; + else + return outerScope->findVarDecl(identifier, exemptDecl); +} + +atl::shared_ptr +For::findVarDeclLocal(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl) const { + return nullptr; +} \ No newline at end of file diff --git a/src/ast/FunCall.cpp b/src/ast/FunCall.cpp index 845583c..1071c71 100644 --- a/src/ast/FunCall.cpp +++ b/src/ast/FunCall.cpp @@ -6,18 +6,6 @@ FunCall::FunCall(const atl::shared_ptr &p_funIdentifier, const atl::vector> &p_funArgs) : funIdentifier(p_funIdentifier), funArgs(p_funArgs) {} -atl::string FunCall::getSignature() const { - atl::string output = funIdentifier->toString() + "("; - const int numArgs = funArgs.size(); - for (int idx = 0; idx < numArgs; ++idx) { - output += funArgs[idx]->getSignature(); - if (idx < numArgs - 1) - output += ", "; - } - output += ")"; - return output; -} - bool FunCall::operator==(Expr &rhs) const { if (rhs.astClass() == astClass()) return *this == *static_cast(&rhs); diff --git a/src/ast/FunDecl.cpp b/src/ast/FunDecl.cpp index 20528f3..a5db7fc 100644 --- a/src/ast/FunDecl.cpp +++ b/src/ast/FunDecl.cpp @@ -1,4 +1,8 @@ #include "ast/FunDecl.h" +#include "ast/ClassType.h" +#include "ast/ClassTypeDef.h" +#include "ast/FunDef.h" +#include "ast/VarDef.h" using namespace ACC; @@ -13,24 +17,14 @@ atl::shared_ptr FunDecl::getIdentifier() const { return funIdentifier; } -atl::string FunDecl::getSignature() const { - atl::string output = getIdentifier()->toString(); +const FunSignature FunDecl::getSignature() const { + atl::vector> paramTypes; + for (int idx = 0; idx < funParams.size(); ++idx) + paramTypes.push_back(funParams[idx]->type); - output += "("; - - for (unsigned int idx = 0; idx < funParams.size(); ++idx) { - output += funParams[idx]->type->getSignature(); - if (idx != funParams.size() - 1) { - output += ", "; - } - } - - output += ")"; - - return output; + return FunSignature(funType, funIdentifier, paramTypes); } - bool FunDecl::operator==(Decl &rhs) const { if (rhs.astClass() == astClass()) return *this == *static_cast(&rhs); @@ -60,3 +54,39 @@ bool FunDecl::operator==(const FunDecl &rhs) const { } bool FunDecl::operator!=(const FunDecl &rhs) const { return !(*this == rhs); } + +atl::shared_ptr +FunDecl::findClassDecl(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl) const { + return outerScope->findClassDecl(identifier, exemptDecl); +} + +atl::shared_ptr +FunDecl::findClassDef(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl) const { + return outerScope->findClassDef(identifier, exemptDecl); +} + +atl::shared_ptr +FunDecl::findFunDecl(const FunSignature &funSignature, + const atl::shared_ptr &exemptDecl) const { + return outerScope->findFunDecl(funSignature, exemptDecl); +} + +atl::shared_ptr +FunDecl::findFunDeclLocal(const FunSignature &funSignature, + const atl::shared_ptr &exemptDecl) const { + return nullptr; +} + +atl::shared_ptr +FunDecl::findVarDecl(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl) const { + return outerScope->findVarDecl(identifier, exemptDecl); +} + +atl::shared_ptr +FunDecl::findVarDeclLocal(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl) const { + return nullptr; +} \ No newline at end of file diff --git a/src/ast/FunDef.cpp b/src/ast/FunDef.cpp index 2d25038..52e7e38 100644 --- a/src/ast/FunDef.cpp +++ b/src/ast/FunDef.cpp @@ -1,4 +1,9 @@ #include "ast/FunDef.h" +#include "ast/ClassType.h" +#include "ast/ConstructorDef.h" +#include "ast/FunDef.h" +#include "ast/PointerType.h" +#include "ast/VarDecl.h" using namespace ACC; @@ -61,7 +66,64 @@ bool FunDef::operator==(const FunDef &rhs) const { if (*funParams[i]->type != *rhs.funParams[i]->type) return false; + if (*funBlock != *rhs.funBlock) + return false; + return true; } bool FunDef::operator!=(const FunDef &rhs) const { return !(*this == rhs); } + +atl::shared_ptr +FunDef::findClassDecl(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl) const { + return outerScope->findClassDecl(identifier, exemptDecl); +} + +atl::shared_ptr +FunDef::findClassDef(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl) const { + return outerScope->findClassDef(identifier, exemptDecl); +} + +atl::shared_ptr +FunDef::findFunDecl(const FunSignature &funSignature, + const atl::shared_ptr &exemptDecl) const { + return outerScope->findFunDecl(funSignature, exemptDecl); +} + +atl::shared_ptr +FunDef::findFunDeclLocal(const FunSignature &funSignature, + const atl::shared_ptr &exemptDecl) const { + return nullptr; +} + +atl::shared_ptr +FunDef::findVarDecl(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl) const { + const atl::shared_ptr localFind = + findVarDeclLocal(identifier, exemptDecl); + if (localFind != nullptr) + return localFind; + else if (outerScope != nullptr) + return outerScope->findVarDecl(identifier, exemptDecl); + else + return nullptr; +} + +atl::shared_ptr +FunDef::findVarDeclLocal(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl) const { + const int numParams = funParams.size(); + for (int idx = 0; idx < numParams; ++idx) { + const atl::shared_ptr currParam = funParams[idx]; + if (currParam.get() == exemptDecl.get()) + continue; + if (*currParam->getIdentifier() != *identifier) + continue; + + return currParam; + } + + return nullptr; +} \ No newline at end of file diff --git a/src/ast/Identifier.cpp b/src/ast/Identifier.cpp index c23b5de..8723c3e 100644 --- a/src/ast/Identifier.cpp +++ b/src/ast/Identifier.cpp @@ -11,6 +11,29 @@ Identifier::Identifier(const atl::string &p_value, const atl::shared_ptr &p_parentIdentifier) : value(p_value), parentIdentifier(p_parentIdentifier) {} +const unsigned int Identifier::namespaceCount() const { + unsigned int output = 0; + atl::shared_ptr currParent = parentIdentifier; + while (currParent != nullptr) { + ++output; + currParent = currParent->parentIdentifier; + } + return output; +} + +const atl::shared_ptr Identifier::namespaceHead() const { + atl::shared_ptr parentIdent = parentIdentifier; + while (parentIdent->parentIdentifier != nullptr) { + parentIdent = parentIdent->parentIdentifier; + } + return parentIdent; +} + +const atl::shared_ptr Identifier::namespaceTail() const { + const unsigned int numNamespaces = namespaceCount(); + return deepCopyIdentifier(numNamespaces - 1); +} + atl::string Identifier::toString() const { atl::string output = value; if (parentIdentifier) { @@ -36,3 +59,27 @@ bool Identifier::operator==(const Identifier &rhs) const { bool Identifier::operator!=(const Identifier &rhs) const { return !(*this == rhs); } + +const atl::shared_ptr +Identifier::deepCopyIdentifier(const unsigned int depth) const { + // Create the new 'root' identifier. + atl::shared_ptr output(new Identifier(value)); + + // Alias the new Identifier. + atl::shared_ptr currCopy = output; + atl::shared_ptr thisParent = parentIdentifier; + + for (unsigned int idx = 0; idx < depth; ++idx) { + // Create a new parent using the original Identifier. + atl::shared_ptr newParent( + new Identifier(thisParent->value)); + // Set the parent of the curr copy to be the new parent. + currCopy->parentIdentifier = newParent; + + // Point the copy/original alias to their parents. + currCopy = currCopy->parentIdentifier; + thisParent = thisParent->parentIdentifier; + } + + return output; +} \ No newline at end of file diff --git a/src/ast/IntLiteral.cpp b/src/ast/IntLiteral.cpp index 7d9d40d..ed425c2 100644 --- a/src/ast/IntLiteral.cpp +++ b/src/ast/IntLiteral.cpp @@ -2,8 +2,11 @@ using namespace ACC; -IntLiteral::IntLiteral(const atl::string &p_literal) : Literal(p_literal) {} - +IntLiteral::IntLiteral(const atl::string &p_literal) + : Literal(IntLiteral::removeSigned(p_literal)), isUnsigned(false) { + if (p_literal[p_literal.size() - 1] == 'u') + isUnsigned = true; +} bool IntLiteral::operator==(Expr &rhs) const { if (rhs.astClass() == astClass()) diff --git a/src/ast/MemberAccess.cpp b/src/ast/MemberAccess.cpp index 8eb38d5..264b69a 100644 --- a/src/ast/MemberAccess.cpp +++ b/src/ast/MemberAccess.cpp @@ -8,8 +8,6 @@ MemberAccess::MemberAccess(const atl::shared_ptr &p_object, : accessType(p_accessType), object(p_object), fieldVariable(p_fieldVariable) {} -atl::string MemberAccess::getSignature() const { return "TODO"; } - bool MemberAccess::operator==(Expr &rhs) const { if (rhs.astClass() == astClass()) return *this == *static_cast(&rhs); diff --git a/src/ast/MemberCall.cpp b/src/ast/MemberCall.cpp index 97d904d..e894638 100644 --- a/src/ast/MemberCall.cpp +++ b/src/ast/MemberCall.cpp @@ -7,8 +7,6 @@ MemberCall::MemberCall(const atl::shared_ptr &p_object, const SourceToken::Class &p_accessType) : accessType(p_accessType), object(p_object), funCall(p_funCall) {} -atl::string MemberCall::getSignature() const { return funCall->getSignature(); } - bool MemberCall::operator==(Expr &rhs) const { if (rhs.astClass() == astClass()) return *this == *static_cast(&rhs); diff --git a/src/ast/Namespace.cpp b/src/ast/Namespace.cpp index 21ab8cd..d4ddfa9 100644 --- a/src/ast/Namespace.cpp +++ b/src/ast/Namespace.cpp @@ -1,4 +1,8 @@ #include "ast/Namespace.h" +#include "ast/ClassType.h" +#include "ast/ClassTypeDef.h" +#include "ast/FunDef.h" +#include "ast/VarDef.h" using namespace ACC; @@ -27,4 +31,132 @@ bool Namespace::operator==(const Namespace &rhs) const { bool Namespace::operator!=(const Namespace &rhs) const { return !(*this == rhs); +} + +atl::shared_ptr +Namespace::findClassDecl(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl) const { + for (int idx = namespaceDeclsChecked - 1; idx >= 0; --idx) { + const atl::shared_ptr currDecl = namespaceDecls[idx]; + if (currDecl->astClass() != "ClassTypeDecl" && + currDecl->astClass() != "ClassTypeDef") + continue; + if (currDecl.get() == exemptDecl.get()) + continue; + if (*currDecl->getIdentifier() != *identifier) + continue; + + return atl::static_pointer_cast(currDecl); + } + if (outerScope != nullptr) + return outerScope->findClassDecl(identifier, exemptDecl); + + return nullptr; +} + +atl::shared_ptr +Namespace::findClassDef(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl) const { + for (int idx = namespaceDeclsChecked - 1; idx >= 0; --idx) { + const atl::shared_ptr currDecl = namespaceDecls[idx]; + if (currDecl->astClass() != "ClassTypeDecl" && + currDecl->astClass() != "ClassTypeDef") + continue; + if (currDecl.get() == exemptDecl.get()) + continue; + if (*currDecl->getIdentifier() == *identifier) + continue; + + return atl::static_pointer_cast(currDecl); + } + if (outerScope != nullptr) + return outerScope->findClassDef(identifier, exemptDecl); + + return nullptr; +} + +atl::shared_ptr +Namespace::findFunDecl(const FunSignature &funSignature, + const atl::shared_ptr &exemptDecl) const { + const atl::shared_ptr localFind = + findFunDeclLocal(funSignature, exemptDecl); + if (localFind != nullptr) + return localFind; + else if (outerScope != nullptr) + return outerScope->findFunDecl(funSignature, exemptDecl); + else + return nullptr; +} + +atl::shared_ptr +Namespace::findFunDeclLocal(const FunSignature &funSignature, + const atl::shared_ptr &exemptDecl) const { + if (funSignature.namespaceCount() > 0) { + for (int idx = namespaceDeclsChecked - 1; idx >= 0; --idx) { + const atl::shared_ptr currDecl = namespaceDecls[idx]; + if (currDecl->astClass() != "Namespace") + continue; + const atl::shared_ptr currNamespace = + atl::static_pointer_cast(currDecl); + if (*currNamespace->identifier != *funSignature.namespaceHead()) + continue; + + const atl::shared_ptr namespaceFind = + currNamespace->findFunDeclLocal(funSignature.lowerNamespace()); + if (namespaceFind == nullptr) + continue; + + return namespaceFind; + } + + return nullptr; + } else { + /* No Namespacing on this FunSignature, search top level. */ + for (int idx = namespaceDeclsChecked - 1; idx >= 0; --idx) { + const atl::shared_ptr currDecl = namespaceDecls[idx]; + if (currDecl->astClass() != "FunDecl" && currDecl->astClass() != "FunDef") + continue; + const atl::shared_ptr currFunDecl = + atl::static_pointer_cast(currDecl); + if (currFunDecl.get() == exemptDecl.get()) + continue; + if (funSignature != currFunDecl->getSignature()) + continue; + + return currFunDecl; + } + + return nullptr; + } +} + +atl::shared_ptr +Namespace::findVarDecl(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl) const { + const atl::shared_ptr localFind = + findVarDeclLocal(identifier, exemptDecl); + if (localFind != nullptr) + return localFind; + else if (outerScope != nullptr) + return outerScope->findVarDecl(identifier, exemptDecl); + else + return nullptr; +} + +atl::shared_ptr +Namespace::findVarDeclLocal(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl) const { + for (int idx = namespaceDeclsChecked - 1; idx >= 0; --idx) { + const atl::shared_ptr currDecl = namespaceDecls[idx]; + if (currDecl->astClass() != "VarDecl" && currDecl->astClass() != "VarDef") + continue; + if (currDecl.get() == exemptDecl.get()) + continue; + if (*currDecl->getIdentifier() != *identifier) + continue; + + return atl::static_pointer_cast(currDecl); + } + + return nullptr; } \ No newline at end of file diff --git a/src/ast/PointerType.cpp b/src/ast/PointerType.cpp index bc80c2f..30284b6 100644 --- a/src/ast/PointerType.cpp +++ b/src/ast/PointerType.cpp @@ -7,11 +7,7 @@ using namespace ACC; PointerType::PointerType(const atl::shared_ptr &p_pointedType) : pointedType(p_pointedType) {} -int PointerType::getBytes() const { return 4; } - -atl::string PointerType::getSignature() const { - return pointedType->getSignature() + "*"; -} +unsigned int PointerType::getBytes() const { return 4; } bool PointerType::operator==(Type &rhs) const { if (rhs.astClass() == "ArrayType") { diff --git a/src/ast/PrefixOp.cpp b/src/ast/PrefixOp.cpp index 13cea41..d01504c 100644 --- a/src/ast/PrefixOp.cpp +++ b/src/ast/PrefixOp.cpp @@ -1,4 +1,3 @@ - #include "ast/PrefixOp.h" using namespace ACC; @@ -7,8 +6,6 @@ PrefixOp::PrefixOp(const Op p_operation, const atl::shared_ptr &p_variable) : operation(p_operation), variable(p_variable) {} -atl::string PrefixOp::getSignature() const { return "int"; } - bool PrefixOp::operator==(Expr &rhs) const { if (rhs.astClass() == astClass()) return *this == *static_cast(&rhs); diff --git a/src/ast/Program.cpp b/src/ast/Program.cpp index 82d152c..0bc0c70 100644 --- a/src/ast/Program.cpp +++ b/src/ast/Program.cpp @@ -1,16 +1,153 @@ #include "ast/Program.h" +#include "ast/ClassType.h" +#include "ast/ClassTypeDef.h" +#include "ast/FunDef.h" +#include "ast/VarDef.h" using namespace ACC; Program::Program(const atl::vector> &p_decls) - : decls(p_decls), globalScope(nullptr) { - for (unsigned int idx = 0; idx < decls.size(); ++idx) { - const atl::shared_ptr decl = decls[idx]; - if (decl->astClass() == "FunDef" || decl->astClass() == "FunDecl") { - funDecls.push_back(atl::static_pointer_cast(decl)); + : decls(p_decls) {} + +atl::shared_ptr +Program::findClassDecl(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl) const { + for (int idx = declsChecked - 1; idx >= 0; --idx) { + const atl::shared_ptr currDecl = decls[idx]; + if (currDecl->astClass() != "ClassTypeDecl" && + currDecl->astClass() != "ClassTypeDef") + continue; + if (currDecl.get() == exemptDecl.get()) + continue; + if (*currDecl->getIdentifier() != *identifier) + continue; + + return atl::static_pointer_cast(currDecl); + } + if (outerScope != nullptr) + return outerScope->findClassDecl(identifier, exemptDecl); + + return nullptr; +} + +atl::shared_ptr +Program::findClassDef(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl) const { + for (int idx = declsChecked - 1; idx >= 0; --idx) { + const atl::shared_ptr currDecl = decls[idx]; + if (currDecl->astClass() != "ClassTypeDecl" && + currDecl->astClass() != "ClassTypeDef") + continue; + if (currDecl.get() == exemptDecl.get()) + continue; + if (*currDecl->getIdentifier() != *identifier) + continue; + + return atl::static_pointer_cast(currDecl); + } + if (outerScope != nullptr) + return outerScope->findClassDef(identifier, exemptDecl); + + return nullptr; +} + +atl::shared_ptr +Program::findFunDecl(const FunSignature &funSignature, + const atl::shared_ptr &exemptDecl) const { + const atl::shared_ptr localFind = + findFunDeclLocal(funSignature, exemptDecl); + if (localFind != nullptr) + return localFind; + else if (outerScope != nullptr) + return outerScope->findFunDecl(funSignature, exemptDecl); + else + return nullptr; +} + +atl::shared_ptr +Program::findFunDeclLocal(const FunSignature &funSignature, + const atl::shared_ptr &exemptDecl) const { + if (funSignature.namespaceCount() > 0) { + for (int idx = declsChecked - 1; idx >= 0; --idx) { + const atl::shared_ptr currDecl = decls[idx]; + if (currDecl->astClass() == "ClassTypeDef") { + const atl::shared_ptr currClassTypeDef = + atl::static_pointer_cast(currDecl); + if (*currClassTypeDef->getIdentifier() != *funSignature.namespaceHead()) + continue; + if (currClassTypeDef.get() == exemptDecl.get()) + continue; + + const atl::shared_ptr classTypeDefFind = + currClassTypeDef->findFunDeclLocal(funSignature.lowerNamespace(), + exemptDecl); + if (classTypeDefFind == nullptr) + continue; + + return classTypeDefFind; + } else if (currDecl->astClass() == "Namespace") { + const atl::shared_ptr currNamespace = + atl::static_pointer_cast(currDecl); + if (*currNamespace->identifier != *funSignature.namespaceHead()) + continue; + + const atl::shared_ptr namespaceFind = + currNamespace->findFunDeclLocal(funSignature.lowerNamespace()); + if (namespaceFind == nullptr) + continue; + + return namespaceFind; + } } - if (decl->astClass() == "VarDecl") { - globalVars.push_back(atl::static_pointer_cast(decl)); + + return nullptr; + } else { + /* No Namespacing on this FunSignature, search top level. */ + for (int idx = declsChecked - 1; idx >= 0; --idx) { + const atl::shared_ptr currDecl = decls[idx]; + if (currDecl->astClass() != "FunDecl" && currDecl->astClass() != "FunDef") + continue; + const atl::shared_ptr currFunDecl = + atl::static_pointer_cast(currDecl); + if (currFunDecl.get() == exemptDecl.get()) + continue; + if (funSignature != currFunDecl->getSignature()) + continue; + + return currFunDecl; } + + return nullptr; } } + +atl::shared_ptr +Program::findVarDecl(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl) const { + const atl::shared_ptr localFind = + findVarDeclLocal(identifier, exemptDecl); + if (localFind != nullptr) + return localFind; + else if (outerScope != nullptr) + return outerScope->findVarDecl(identifier, exemptDecl); + else + return nullptr; +} + +atl::shared_ptr +Program::findVarDeclLocal(const atl::shared_ptr identifier, + const atl::shared_ptr &exemptDecl) const { + for (int idx = declsChecked - 1; idx >= 0; --idx) { + const atl::shared_ptr currDecl = decls[idx]; + if (currDecl->astClass() != "VarDecl" && currDecl->astClass() != "VarDef") + continue; + if (currDecl.get() == exemptDecl.get()) + continue; + if (*currDecl->getIdentifier() != *identifier) + continue; + + return atl::static_pointer_cast(currDecl); + } + + return nullptr; +} \ No newline at end of file diff --git a/src/ast/ReferenceType.cpp b/src/ast/ReferenceType.cpp index 5c4e670..7fa11f3 100644 --- a/src/ast/ReferenceType.cpp +++ b/src/ast/ReferenceType.cpp @@ -5,11 +5,7 @@ using namespace ACC; ReferenceType::ReferenceType(const atl::shared_ptr &p_referencedType) : referencedType(p_referencedType) {} -int ReferenceType::getBytes() const { return 4; } - -atl::string ReferenceType::getSignature() const { - return referencedType->getSignature() + "&"; -} +unsigned int ReferenceType::getBytes() const { return 4; } bool ReferenceType::operator==(Type &rhs) const { if (referencedType->astClass() == rhs.astClass()) { diff --git a/src/ast/Scope.cpp b/src/ast/Scope.cpp deleted file mode 100644 index 64a4353..0000000 --- a/src/ast/Scope.cpp +++ /dev/null @@ -1,162 +0,0 @@ -#include "ast/Scope.h" -#include "ast/ClassType.h" -#include "ast/FunDecl.h" - -using namespace ACC; - -Scope::Scope() : decls({}), outerScope(nullptr) {} - -void Scope::insertDecl(const atl::shared_ptr &decl) { - decls.push_back(decl); -} - -atl::shared_ptr -Scope::findClassDecl(const atl::shared_ptr identifier) const { - for (int idx = decls.size() - 1; idx >= 0; --idx) { - if (decls[idx]->astClass() != "ClassTypeDecl" && - decls[idx]->astClass() != "ClassTypeDef") - continue; - if (*decls[idx]->getIdentifier() == *identifier) { - return atl::static_pointer_cast(decls[idx]); - } - } - if (outerScope != nullptr) - return outerScope->findClassDecl(identifier); - - return nullptr; -} - -atl::shared_ptr -Scope::findClassDef(const atl::shared_ptr identifier) const { - for (int idx = decls.size() - 1; idx >= 0; --idx) { - if (decls[idx]->astClass() != "ClassTypeDecl" && - decls[idx]->astClass() != "ClassTypeDef") - continue; - if (*decls[idx]->getIdentifier() == *identifier) { - return atl::static_pointer_cast(decls[idx]); - } - } - if (outerScope != nullptr) - return outerScope->findClassDef(identifier); - - return nullptr; -} - -atl::shared_ptr -Scope::findFunDecl(const atl::string &funSignature) const { - const atl::shared_ptr localFind = findFunDeclLocal(funSignature); - if (localFind != nullptr) - return localFind; - else if (outerScope != nullptr) - return outerScope->findFunDecl(funSignature); - else - return nullptr; -} - -atl::shared_ptr -Scope::findFunDeclLocal(const atl::string &funSignature) const { - for (int idx = decls.size() - 1; idx >= 0; --idx) { - if (decls[idx]->astClass() != "FunDecl" && - decls[idx]->astClass() != "FunDef") - continue; - const atl::shared_ptr currFunDecl = - atl::static_pointer_cast(decls[idx]); - if (currFunDecl->getSignature() == funSignature) { - return currFunDecl; - } - } - - return nullptr; -} - -atl::shared_ptr -Scope::findVarDecl(const atl::shared_ptr identifier) const { - const atl::shared_ptr localFind = findVarDeclLocal(identifier); - if (localFind != nullptr) - return localFind; - else if (outerScope != nullptr) - return outerScope->findVarDecl(identifier); - else - return nullptr; -} - -atl::shared_ptr -Scope::findVarDeclLocal(const atl::shared_ptr identifier) const { - for (int idx = decls.size() - 1; idx >= 0; --idx) { - if (decls[idx]->astClass() != "VarDecl" && - decls[idx]->astClass() != "VarDef") - continue; - if (*decls[idx]->getIdentifier() == *identifier) { - return atl::static_pointer_cast(decls[idx]); - } - } - - return nullptr; -} - -atl::shared_ptr -Scope::resolveClassType(const atl::shared_ptr &type) const { - for (int idx = decls.size() - 1; idx >= 0; --idx) { - if (decls[idx]->astClass() == "ClassTypeDecl" || - decls[idx]->astClass() == "ClassTypeDef") { - if (*decls[idx]->getIdentifier() == *type->identifier) - return decls[idx]; - } - } - if (outerScope != nullptr) - return outerScope->resolveClassType(type); - - return nullptr; -} - -atl::shared_ptr -Scope::resolveVarExpr(const atl::shared_ptr identifier) const { - for (int idx = decls.size() - 1; idx >= 0; --idx) { - if (decls[idx]->astClass() == "VarDecl" || - decls[idx]->astClass() == "VarDef") { - if (*decls[idx]->getIdentifier() == *identifier) - return decls[idx]; - } - } - if (outerScope != nullptr) - return outerScope->resolveVarExpr(identifier); - - return nullptr; -} - -atl::shared_ptr -Scope::resolveFunCall(const atl::string funSignature) const { - for (int idx = decls.size() - 1; idx >= 0; --idx) { - if (decls[idx]->astClass() == "FunDecl" || - decls[idx]->astClass() == "FunDef") { - const atl::shared_ptr currFunDecl = - atl::static_pointer_cast(decls[idx]); - if (currFunDecl->getSignature() == funSignature) - return currFunDecl; - } - } - if (outerScope != nullptr) - return outerScope->resolveFunCall(funSignature); - - return nullptr; -} - -atl::shared_ptr -Scope::duplicateDeclaration(const atl::shared_ptr &decl) const { - const atl::shared_ptr &local = duplicateDeclarationLocal(decl); - if (local == nullptr && outerScope != nullptr) - return outerScope->duplicateDeclaration(decl); - - return local; -} - -atl::shared_ptr -Scope::duplicateDeclarationLocal(const atl::shared_ptr &decl) const { - // Reverse iterate decls. - for (int idx = decls.size() - 1; idx >= 0; --idx) { - if (*decl == *decls[idx]) - return decls[idx]; - } - - return nullptr; -} \ No newline at end of file diff --git a/src/ast/SizeOf.cpp b/src/ast/SizeOf.cpp index 5cde604..0336bb8 100644 --- a/src/ast/SizeOf.cpp +++ b/src/ast/SizeOf.cpp @@ -4,8 +4,6 @@ using namespace ACC; SizeOf::SizeOf(const atl::shared_ptr &p_type) : type(p_type) {} -atl::string SizeOf::getSignature() const { return "int"; } - bool SizeOf::operator==(Expr &rhs) const { if (rhs.astClass() == astClass()) return *this == *static_cast(&rhs); diff --git a/src/ast/StringLiteral.cpp b/src/ast/StringLiteral.cpp index 2b4ebc3..93f47dd 100644 --- a/src/ast/StringLiteral.cpp +++ b/src/ast/StringLiteral.cpp @@ -5,10 +5,6 @@ using namespace ACC; StringLiteral::StringLiteral(const atl::string &p_literal) : Literal(p_literal) {} -atl::string StringLiteral::getSignature() const { - return "char*"; -} - bool StringLiteral::operator==(Expr &rhs) const { if (rhs.astClass() == astClass()) return *this == *static_cast(&rhs); diff --git a/src/ast/SubscriptOp.cpp b/src/ast/SubscriptOp.cpp new file mode 100644 index 0000000..a78edad --- /dev/null +++ b/src/ast/SubscriptOp.cpp @@ -0,0 +1,29 @@ +#include "ast/SubscriptOp.h" + +using namespace ACC; + +SubscriptOp::SubscriptOp(const atl::shared_ptr &p_variable, + const atl::shared_ptr &p_index) + : variable(p_variable), index(p_index), operatorDecl(nullptr) {} + +bool SubscriptOp::operator==(Expr &rhs) const { + if (rhs.astClass() == astClass()) + return *this == *static_cast(&rhs); + return false; +} + +bool SubscriptOp::operator!=(Expr &rhs) const { return !(*this == rhs); } + +bool SubscriptOp::operator==(const SubscriptOp &rhs) const { + if (*index != *rhs.index) + return false; + + if (*variable != *rhs.variable) + return false; + + return true; +} + +bool SubscriptOp::operator!=(const SubscriptOp &rhs) const { + return !(*this == rhs); +} diff --git a/src/ast/TertiaryExpr.cpp b/src/ast/TertiaryExpr.cpp index c2323c0..29369de 100644 --- a/src/ast/TertiaryExpr.cpp +++ b/src/ast/TertiaryExpr.cpp @@ -8,10 +8,6 @@ TertiaryExpr::TertiaryExpr(const atl::shared_ptr &p_tertiaryCondition, : tertiaryCondition(p_tertiaryCondition), tertiaryIfBody(p_tertiaryIfBody), tertiaryElseBody(p_tertiaryElseBody) {} -atl::string TertiaryExpr::getSignature() const { - return tertiaryIfBody->getSignature(); -} - bool TertiaryExpr::operator==(Expr &rhs) const { if (rhs.astClass() == astClass()) return *this == *static_cast(&rhs); diff --git a/src/ast/TypeCast.cpp b/src/ast/TypeCast.cpp index 4c34919..8c67fc1 100644 --- a/src/ast/TypeCast.cpp +++ b/src/ast/TypeCast.cpp @@ -6,8 +6,6 @@ TypeCast::TypeCast(const atl::shared_ptr &p_type, const atl::shared_ptr &p_expr) : type(p_type), expr(p_expr) {} -atl::string TypeCast::getSignature() const { return type->getSignature(); } - bool TypeCast::operator==(Expr &rhs) const { if (rhs.astClass() == astClass()) return *this == *static_cast(&rhs); diff --git a/src/ast/ValueAt.cpp b/src/ast/ValueAt.cpp index 581fccd..0fd8e64 100644 --- a/src/ast/ValueAt.cpp +++ b/src/ast/ValueAt.cpp @@ -5,15 +5,6 @@ using namespace ACC; ValueAt::ValueAt(const atl::shared_ptr &p_derefExpr) : derefExpr(p_derefExpr) {} -atl::string ValueAt::getSignature() const { - const atl::string derefExprSig = derefExpr->getSignature(); - atl::string output; - for (int idx = 0; idx < derefExprSig.length() - 1; ++idx) - output += derefExprSig[idx]; - - return output; -} - bool ValueAt::operator==(Expr &rhs) const { if (rhs.astClass() == astClass()) return *this == *static_cast(&rhs); diff --git a/src/ast/VarDecl.cpp b/src/ast/VarDecl.cpp index 12be6ae..0ffef15 100644 --- a/src/ast/VarDecl.cpp +++ b/src/ast/VarDecl.cpp @@ -6,7 +6,7 @@ VarDecl::VarDecl(const atl::shared_ptr &p_type, const atl::shared_ptr &p_identifier) : type(p_type), identifier(p_identifier) {} -int VarDecl::getBytes() const { return type->getBytes(); } +unsigned int VarDecl::getBytes() const { return type->getBytes(); } atl::shared_ptr VarDecl::getIdentifier() const { return identifier; diff --git a/src/ast/VarDef.cpp b/src/ast/VarDef.cpp index a0d54ba..c0c270b 100644 --- a/src/ast/VarDef.cpp +++ b/src/ast/VarDef.cpp @@ -7,7 +7,7 @@ VarDef::VarDef(const atl::shared_ptr &p_varType, const atl::shared_ptr &p_varValue) : VarDecl(p_varType, p_varidentifier), varValue(p_varValue) {} -int VarDef::getBytes() const { return type->getBytes(); } +unsigned int VarDef::getBytes() const { return type->getBytes(); } atl::shared_ptr VarDef::getIdentifier() const { return identifier; } diff --git a/src/passes/DotGraph.cpp b/src/passes/DotGraph.cpp index 4b4aa86..120e772 100644 --- a/src/passes/DotGraph.cpp +++ b/src/passes/DotGraph.cpp @@ -39,18 +39,6 @@ atl::string DotGraph::visit(Allocation &a) { return allocationID; } } -atl::string DotGraph::visit(ArrayAccess &aa) { - const atl::string arrayAccessID = "ArrayAccess" + atl::to_string(++nodeCount); - declare(arrayAccessID, "ArrayAccess"); - - const atl::string arrayID = aa.array->accept(*this); - const atl::string indexID = aa.index->accept(*this); - - join(arrayAccessID, arrayID); - join(arrayAccessID, indexID); - - return arrayAccessID; -} atl::string DotGraph::visit(ArrayType &at) { const atl::string arrayTypeID = "ArrayType" + atl::to_string(++nodeCount); declare(arrayTypeID, at.pointedType->accept(*this) + "[]"); @@ -221,6 +209,15 @@ atl::string DotGraph::visit(ClassTypeDef &ctd) { classTypeDeclIDs[ctd.classType->identifier->toString().c_str()] = classID; return classID; } +atl::string DotGraph::visit(ConstructorCall &cc) { + const atl::string funCallID = "ConstructorCall" + atl::to_string(++nodeCount); + declare(funCallID, cc.constructorIdentifier->toString() + "()"); + + for (unsigned int idx = 0; idx < cc.constructorArgs.size(); ++idx) + join(funCallID, cc.constructorArgs[idx]->accept(*this)); + + return funCallID; +} atl::string DotGraph::visit(ConstructorDecl &cd) { const atl::string constructorID = "ConstructorDecl" + atl::to_string(++nodeCount); @@ -472,6 +469,18 @@ atl::string DotGraph::visit(StringLiteral &sl) { declare(strID, "\\\"" + sl.getLiteral() + "\\\""); return strID; } +atl::string DotGraph::visit(SubscriptOp &so) { + const atl::string subscriptOpID = "SubscriptOp" + atl::to_string(++nodeCount); + declare(subscriptOpID, "SubscriptOp"); + + const atl::string arrayID = so.variable->accept(*this); + const atl::string indexID = so.index->accept(*this); + + join(subscriptOpID, arrayID); + join(subscriptOpID, indexID); + + return subscriptOpID; +} atl::string DotGraph::visit(TertiaryExpr &t) { const atl::string tertiaryID = "TertiaryExpr" + atl::to_string(++nodeCount); const atl::string conditionID = t.tertiaryCondition->accept(*this); @@ -524,7 +533,7 @@ atl::string DotGraph::visit(VarDef &vd) { } atl::string DotGraph::visit(VarExpr &ve) { const atl::string varID = "VarExpr" + atl::to_string(++nodeCount); - declare(varID, ve.varIdentifier->toString().c_str()); + declare(varID, ve.varIdentifier->toString()); return varID; } atl::string DotGraph::visit(While &w) { diff --git a/src/passes/Optimiser.cpp b/src/passes/Optimiser.cpp index 958889c..9b5a7c4 100644 --- a/src/passes/Optimiser.cpp +++ b/src/passes/Optimiser.cpp @@ -26,10 +26,6 @@ void Optimiser::run() { atl::shared_ptr Optimiser::visit(AddressOf &ao) { return ao.getptr(); } atl::shared_ptr Optimiser::visit(Allocation &a) { return a.getptr(); } -atl::shared_ptr Optimiser::visit(ArrayAccess &aa) { - aa.array = atl::static_pointer_cast(aa.array->accept(*this)); - return aa.getptr(); -} atl::shared_ptr Optimiser::visit(ArrayType &at) { return at.getptr(); } atl::shared_ptr Optimiser::visit(Assign &as) { as.lhs = as.lhs->accept(*this); @@ -129,6 +125,12 @@ atl::shared_ptr Optimiser::visit(ClassTypeDecl &ctd) { atl::shared_ptr Optimiser::visit(ClassTypeDef &ctd) { return ctd.getptr(); } +atl::shared_ptr Optimiser::visit(ConstructorCall &cc) { + for (unsigned int idx = 0; idx < cc.constructorArgs.size(); ++idx) + cc.constructorArgs[idx] = + atl::static_pointer_cast(cc.constructorArgs[idx]->accept(*this)); + return cc.getptr(); +} atl::shared_ptr Optimiser::visit(ConstructorDecl &cd) { return cd.getptr(); } @@ -207,11 +209,10 @@ atl::shared_ptr Optimiser::visit(PointerType &pt) { } atl::shared_ptr Optimiser::visit(PrefixOp &po) { return po.getptr(); } atl::shared_ptr Optimiser::visit(Program &p) { - currScope = atl::make_shared(Block({})); + currScope = p.getptr(); for (unsigned int idx = 0; idx < p.decls.size(); ++idx) p.decls[idx] = atl::static_pointer_cast(p.decls[idx]->accept(*this)); - p.globalScope = currScope; return nullptr; } atl::shared_ptr Optimiser::visit(ReferenceType &rt) { @@ -226,6 +227,11 @@ atl::shared_ptr Optimiser::visit(SizeOf &so) { return so.getptr(); } atl::shared_ptr Optimiser::visit(StringLiteral &sl) { return sl.getptr(); } +atl::shared_ptr Optimiser::visit(SubscriptOp &so) { + so.variable = so.variable->accept(*this); + so.index = so.index->accept(*this); + return so.getptr(); +} atl::shared_ptr Optimiser::visit(TertiaryExpr &t) { return t.getptr(); } diff --git a/src/passes/SemanticAnalysis.cpp b/src/passes/SemanticAnalysis.cpp index 8e9750f..51bda9c 100644 --- a/src/passes/SemanticAnalysis.cpp +++ b/src/passes/SemanticAnalysis.cpp @@ -6,7 +6,7 @@ using namespace ACC; SemanticAnalysis::SemanticAnalysis(atl::shared_ptr progAST) - : progAST(progAST), inClassTypeDef(false) {} + : progAST(progAST) {} atl::shared_ptr SemanticAnalysis::error(const atl::string &errorType, const atl::string &error, @@ -18,8 +18,10 @@ SemanticAnalysis::error(const atl::string &errorType, const atl::string &error, } void SemanticAnalysis::printErrors() { - printf("Semantic Analysis Errors:\n"); - for (unsigned int idx = 0; idx < errors.size(); ++idx) + const unsigned int num_errors = errors.size(); + if (num_errors > 0) + printf("Semantic Analysis Errors:\n"); + for (unsigned int idx = 0; idx < num_errors; ++idx) printf("\t%s\n", errors[idx].c_str()); } @@ -51,25 +53,6 @@ atl::shared_ptr SemanticAnalysis::visit(Allocation &a) { return atl::shared_ptr( new PointerType(a.varConstructorCall->accept(*this))); } -atl::shared_ptr SemanticAnalysis::visit(ArrayAccess &aa) { - const atl::shared_ptr arrayExprType = aa.array->accept(*this); - const atl::shared_ptr arrayIndex = aa.index->accept(*this); - if (arrayExprType->astClass() != "ArrayType" && - arrayExprType->astClass() != "PointerType") - return error("Type Analysis", - "Attempted to index an expression which was not an array. Was " - "of type: " + - arrayExprType->astClass(), - aa.array); - if (arrayIndex->astClass() != "BaseType") - return error("Type Analysis", - "Attempted to index an array using an expression which was " - "not of type int. Was of type: " + - arrayIndex->astClass(), - aa.index); - - return atl::static_pointer_cast(arrayExprType)->pointedType; -} atl::shared_ptr SemanticAnalysis::visit(ArrayType &at) { return at.getptr(); } @@ -77,10 +60,7 @@ atl::shared_ptr SemanticAnalysis::visit(Assign &as) { const atl::shared_ptr lhsType = as.lhs->accept(*this); const atl::shared_ptr rhsType = as.rhs->accept(*this); if (*lhsType != *rhsType) - return error("Type Analysis", - "Assignation has mismatched types. (" + - lhsType->getSignature() + " = " + rhsType->getSignature() + - ")", + return error("Type Analysis", "Assignation has mismatched types.", as.getptr()); return atl::shared_ptr(new BaseType(PrimitiveType::NULLPTR_T)); } @@ -91,10 +71,7 @@ atl::shared_ptr SemanticAnalysis::visit(BinOp &bo) { const atl::shared_ptr lhsType = bo.lhs->accept(*this); const atl::shared_ptr rhsType = bo.rhs->accept(*this); if (*lhsType != *rhsType) - return error("Type Analysis", - "Binary operation has mismatched types. (" + - lhsType->getSignature() + ", " + rhsType->getSignature() + - ")", + return error("Type Analysis", "Binary operation has mismatched types.", bo.getptr()); switch (bo.operation) { @@ -132,8 +109,10 @@ atl::shared_ptr SemanticAnalysis::visit(Block &b) { b.outerScope = currScope; currScope = b.getptr(); - for (unsigned int idx = 0; idx < b.stmts.size(); ++idx) + for (unsigned int idx = 0; idx < b.stmts.size(); ++idx) { b.stmts[idx]->accept(*this); + ++b.stmtsChecked; + } currScope = b.outerScope; return atl::shared_ptr(new BaseType(PrimitiveType::NULLPTR_T)); @@ -146,7 +125,7 @@ atl::shared_ptr SemanticAnalysis::visit(CharLiteral &cl) { } atl::shared_ptr SemanticAnalysis::visit(ClassType &ct) { const atl::shared_ptr ctd = - currScope->findClassDecl(ct.identifier); + currScope->findClassDef(ct.identifier); if (ctd == nullptr) return error("Name Analysis", @@ -158,40 +137,54 @@ atl::shared_ptr SemanticAnalysis::visit(ClassType &ct) { return ct.getptr(); } atl::shared_ptr SemanticAnalysis::visit(ClassTypeDecl &ctd) { - if (currScope->findClassDef(ctd.getIdentifier())) + if (currScope->findClassDef(ctd.getIdentifier(), ctd.getptr())) return error("Name Analysis", "Attempted to declare a Class with an identifier that is " "already in use: " + ctd.getIdentifier()->toString(), ctd.getptr()); - currScope->insertDecl(ctd.getptr()); return ctd.classType; } atl::shared_ptr SemanticAnalysis::visit(ClassTypeDef &ctd) { - if (currScope->findClassDef(ctd.getIdentifier())) + if (currScope->findClassDef(ctd.getIdentifier(), ctd.getptr())) return error("Name Analysis", "Attempted to declare a Class with an identifier that is " "already in use: " + ctd.getIdentifier()->toString(), ctd.getptr()); - currScope->insertDecl(ctd.getptr()); - inClassTypeDef = true; ctd.outerScope = currScope; currScope = ctd.getptr(); - for (unsigned int idx = 0; idx < ctd.classDecls.size(); ++idx) - currScope->insertDecl(ctd.classDecls[idx]); - for (unsigned int idx = 0; idx < ctd.classDecls.size(); ++idx) ctd.classDecls[idx]->accept(*this); currScope = ctd.outerScope; - inClassTypeDef = false; return ctd.classType; } +atl::shared_ptr SemanticAnalysis::visit(ConstructorCall &cc) { + const atl::shared_ptr ctorClassTypeDef = + currScope->findClassDef(cc.constructorIdentifier); + + atl::vector> constructorCallArgTypes; + constructorCallArgTypes.push_back(atl::shared_ptr( + new PointerType(ctorClassTypeDef->classType))); + for (unsigned int idx = 0; idx < cc.constructorArgs.size(); ++idx) + constructorCallArgTypes.push_back(cc.constructorArgs[idx]->accept(*this)); + + const FunSignature ctorCallSignature(nullptr, cc.constructorIdentifier, + constructorCallArgTypes); + const atl::shared_ptr ctorDecl = + ctorClassTypeDef->findConstructorDecl(ctorCallSignature); + if (ctorDecl == nullptr) + return error("Type Analysis", "Attempted to call undeclared constructor.", + cc.getptr()); + + cc.constructorDecl = ctorDecl; + return cc.constructorDecl->classType; +} atl::shared_ptr SemanticAnalysis::visit(ConstructorDecl &cd) { cd.outerScope = currScope; currScope = cd.getptr(); @@ -207,15 +200,10 @@ atl::shared_ptr SemanticAnalysis::visit(ConstructorDef &cd) { cd.outerScope = currScope; currScope = cd.getptr(); - const bool inClassTypeDef_temp = inClassTypeDef; - inClassTypeDef = false; - for (unsigned int idx = 0; idx < cd.constructorParams.size(); ++idx) cd.constructorParams[idx]->accept(*this); cd.constructorBlock->accept(*this); - inClassTypeDef = inClassTypeDef_temp; - currScope = cd.outerScope; return cd.classType; @@ -228,13 +216,8 @@ atl::shared_ptr SemanticAnalysis::visit(DestructorDecl &dd) { return atl::shared_ptr(new BaseType(PrimitiveType::NULLPTR_T)); } atl::shared_ptr SemanticAnalysis::visit(DestructorDef &dd) { - const bool inClassTypeDef_temp = inClassTypeDef; - inClassTypeDef = false; - dd.destructorBlock->accept(*this); - inClassTypeDef = inClassTypeDef_temp; - return atl::shared_ptr(new BaseType(PrimitiveType::NULLPTR_T)); } atl::shared_ptr SemanticAnalysis::visit(DoWhile &dw) { @@ -281,12 +264,14 @@ atl::shared_ptr SemanticAnalysis::visit(For &f) { return atl::shared_ptr(new BaseType(PrimitiveType::NULLPTR_T)); } atl::shared_ptr SemanticAnalysis::visit(FunCall &fc) { - // Visit all parameters first. + atl::vector> funCallArgTypes; for (unsigned int idx = 0; idx < fc.funArgs.size(); ++idx) - fc.funArgs[idx]->accept(*this); + funCallArgTypes.push_back(fc.funArgs[idx]->accept(*this)); + const FunSignature funCallSignature(nullptr, fc.funIdentifier, + funCallArgTypes); const atl::shared_ptr funDecl = - currScope->resolveFunCall(fc.getSignature()); + currScope->findFunDecl(funCallSignature); if (funDecl == nullptr) return error("Type Analysis", "Attempted to call undeclared function.", fc.getptr()); @@ -295,47 +280,34 @@ atl::shared_ptr SemanticAnalysis::visit(FunCall &fc) { return fc.funDecl->funType; } atl::shared_ptr SemanticAnalysis::visit(FunDecl &fd) { - if (!inClassTypeDef && currScope->findVarDecl(fd.getIdentifier())) + if (currScope->findVarDecl(fd.getIdentifier(), fd.getptr())) return error("Name Analysis", "FunDecl Identifier already in use: " + fd.getIdentifier()->toString(), fd.getptr()); - if (!inClassTypeDef) - currScope->insertDecl(fd.getptr()); - for (unsigned int idx = 0; idx < fd.funParams.size(); ++idx) fd.funParams[idx]->accept(*this); - return fd.funType; + return fd.funType->accept(*this); } atl::shared_ptr SemanticAnalysis::visit(FunDef &fd) { - if (!inClassTypeDef && currScope->findVarDecl(fd.getIdentifier())) + if (currScope->findVarDecl(fd.getIdentifier(), fd.getptr())) return error("Name Analysis", "FunDef Identifier already in use: " + fd.getIdentifier()->toString(), fd.getIdentifier()); - if (!inClassTypeDef) - currScope->insertDecl(fd.getptr()); - fd.outerScope = currScope; currScope = fd.getptr(); - const bool inClassTypeDef_temp = inClassTypeDef; - inClassTypeDef = false; - for (unsigned int idx = 0; idx < fd.funParams.size(); ++idx) fd.funParams[idx]->accept(*this); fd.funBlock->accept(*this); - inClassTypeDef = inClassTypeDef_temp; - currScope = fd.outerScope; - - return fd.funType; + return fd.funType->accept(*this); } atl::shared_ptr SemanticAnalysis::visit(Identifier &i) { - // TODO? return atl::shared_ptr(new BaseType(PrimitiveType::NULLPTR_T)); } atl::shared_ptr SemanticAnalysis::visit(If &i) { @@ -358,10 +330,14 @@ atl::shared_ptr SemanticAnalysis::visit(If &i) { return atl::shared_ptr(new BaseType(PrimitiveType::NULLPTR_T)); } atl::shared_ptr SemanticAnalysis::visit(IntLiteral &il) { - return atl::shared_ptr(new BaseType(PrimitiveType::INT)); + if (il.isUnsigned) + return atl::shared_ptr(new BaseType(PrimitiveType::UINT)); + else + return atl::shared_ptr(new BaseType(PrimitiveType::INT)); } atl::shared_ptr SemanticAnalysis::visit(MemberAccess &ma) { atl::shared_ptr objType = ma.object->accept(*this); + objType = collapseReferenceTypes(objType); atl::shared_ptr objClassType; if (objType->astClass() == "ClassType") { @@ -385,24 +361,6 @@ atl::shared_ptr SemanticAnalysis::visit(MemberAccess &ma) { "was not an object.", ma.object); objClassType = atl::static_pointer_cast(objType); - } else if (objType->astClass() == "ReferenceType") { - if (ma.accessType != SourceToken::Class::DOT) - return error("Type Analysis", - "Attempted to access member variable of class type without " - "using `.` operator.", - ma.object); - objType = atl::static_pointer_cast(objType)->referencedType; - // Handle T&& - if (objType->astClass() == "ReferenceType") - objType = - atl::static_pointer_cast(objType)->referencedType; - // Get ClassType - if (objType->astClass() != "ClassType") - return error("Type Analysis", - "Attempted to access a member variable on a variable that " - "was not an object.", - ma.object); - objClassType = atl::static_pointer_cast(objType); } else { return error("Type Analysis", "Attempted to access a member variable on a variable that " @@ -431,7 +389,7 @@ atl::shared_ptr SemanticAnalysis::visit(MemberAccess &ma) { } atl::shared_ptr SemanticAnalysis::visit(MemberCall &mc) { atl::shared_ptr objType = mc.object->accept(*this); - // const atl::shared_ptr memberCallType = mc.funCall->accept(*this); + objType = collapseReferenceTypes(objType); atl::shared_ptr objClassType; if (objType->astClass() == "ClassType") { @@ -455,24 +413,6 @@ atl::shared_ptr SemanticAnalysis::visit(MemberCall &mc) { "was not an object.", mc.object); objClassType = atl::static_pointer_cast(objType); - } else if (objType->astClass() == "ReferenceType") { - if (mc.accessType != SourceToken::Class::DOT) - return error("Type Analysis", - "Attempted to call member function of class type without " - "using `.` operator.", - mc.object); - objType = atl::static_pointer_cast(objType)->referencedType; - // Handle T&& - if (objType->astClass() == "ReferenceType") - objType = - atl::static_pointer_cast(objType)->referencedType; - // Get ClassType - if (objType->astClass() != "ClassType") - return error("Type Analysis", - "Attempted to call a member function on a variable that was " - "not an object.", - mc.object); - objClassType = atl::static_pointer_cast(objType); } else { return error("Type Analysis", "Attempted to access a member variable on a variable that " @@ -491,27 +431,32 @@ atl::shared_ptr SemanticAnalysis::visit(MemberCall &mc) { /* Now Manually Visit the Member Call */ // Visit all parameters first. + atl::vector> funCallArgTypes; + funCallArgTypes.push_back(atl::shared_ptr( + new PointerType(objClassTypeDef->classType))); for (unsigned int idx = 0; idx < mc.funCall->funArgs.size(); ++idx) - mc.funCall->funArgs[idx]->accept(*this); + funCallArgTypes.push_back(mc.funCall->funArgs[idx]->accept(*this)); - // Check this ClassTypeDef contains the member. + const FunSignature funCallSignature(nullptr, mc.funCall->funIdentifier, + funCallArgTypes); const atl::shared_ptr memberFunDecl = - objClassTypeDef->findFunDeclLocal(mc.funCall->getSignature()); + objClassTypeDef->findFunDeclLocal(funCallSignature); if (memberFunDecl == nullptr) return error("Type Error", "Attempted to call a member function that does " "not exist in the class definition.", mc.funCall); - // return mc.funCall->accept(*this); return memberFunDecl->funType; } atl::shared_ptr SemanticAnalysis::visit(Namespace &n) { n.outerScope = currScope; currScope = n.getptr(); - for (unsigned int i = 0; i < n.namespaceDecls.size(); ++i) + for (unsigned int i = 0; i < n.namespaceDecls.size(); ++i) { n.namespaceDecls[i]->accept(*this); + ++n.namespaceDeclsChecked; + } currScope = n.outerScope; return atl::shared_ptr(new BaseType(PrimitiveType::NULLPTR_T)); @@ -530,12 +475,13 @@ atl::shared_ptr SemanticAnalysis::visit(PrefixOp &po) { return po.variable->accept(*this); } atl::shared_ptr SemanticAnalysis::visit(Program &p) { - currScope = atl::make_shared(Block({})); + currScope = p.getptr(); - for (unsigned int idx = 0; idx < p.decls.size(); ++idx) + for (unsigned int idx = 0; idx < p.decls.size(); ++idx) { p.decls[idx]->accept(*this); + ++p.declsChecked; + } - p.globalScope = currScope; return atl::shared_ptr(new BaseType(PrimitiveType::NULLPTR_T)); } atl::shared_ptr SemanticAnalysis::visit(ReferenceType &rt) { @@ -555,6 +501,53 @@ atl::shared_ptr SemanticAnalysis::visit(StringLiteral &sl) { return atl::shared_ptr(new PointerType( atl::shared_ptr(new BaseType(PrimitiveType::CHAR)))); } +atl::shared_ptr SemanticAnalysis::visit(SubscriptOp &so) { + atl::shared_ptr objType = so.variable->accept(*this); + objType = collapseReferenceTypes(objType); + if (objType->astClass() == "ArrayType" || + objType->astClass() == "PointerType") { + // TODO: Initialise this FunDef with an implementation. + const atl::shared_ptr arrayPointerSubscriptOpDef; + so.operatorDecl = arrayPointerSubscriptOpDef; + return atl::static_pointer_cast(objType)->pointedType; + } else if (objType->astClass() == "ClassType") { + const atl::shared_ptr objClassType = + atl::static_pointer_cast(objType); + const atl::shared_ptr objClassTypeDef = + objClassType->typeDefinition; + + const atl::shared_ptr indexType = so.index->accept(*this); + + // Create FunSignature for SubscriptOp. + atl::vector> opArgs; + opArgs.push_back( + atl::shared_ptr(new PointerType(objClassType))); + opArgs.push_back(so.index->accept(*this)); + const atl::shared_ptr opIdentifier( + new Identifier("operator[]", objClassType->identifier)); + const FunSignature opSignature(nullptr, opIdentifier, opArgs); + + // TODO: Consider if this should search all the scope, or just the scope for + // the ClassTypeDef already resolved above. The former would allow us to use + // out of class definitions. + const atl::shared_ptr objSubscriptOpDecl = + currScope->findFunDecl(opSignature); + if (objSubscriptOpDecl == nullptr) { + return error("Type Error", + "No definiton for subscript operator[] for type: " + + objClassType->identifier->toString(), + so.variable); + } + + so.operatorDecl = objSubscriptOpDecl; + return objSubscriptOpDecl->funType; + } else { + return error("Type Error", + "Cannot perform subscript operator[] on type: " + + objType->astClass(), + so.variable); + } +} atl::shared_ptr SemanticAnalysis::visit(TertiaryExpr &t) { const atl::shared_ptr conditionType = t.tertiaryCondition->accept(*this); @@ -600,48 +593,41 @@ atl::shared_ptr SemanticAnalysis::visit(ValueAt &va) { } atl::shared_ptr SemanticAnalysis::visit(VarDecl &vd) { if (vd.type->astClass() == "ClassType") { - atl::shared_ptr vdType = - atl::static_pointer_cast(vd.type); - const atl::shared_ptr vdTypeDecl = - currScope->findClassDef(vdType->identifier); - - if (vdTypeDecl == nullptr) + const atl::shared_ptr vdClassType = vd.type->accept(*this); + if (vdClassType->typeDefinition == nullptr) return error("Type Analysis", - "Attempted to declare variable with undefined class type.", + "Attempted to define variable with undefined class type.", atl::static_pointer_cast(vd.getptr())); - vdType->typeDefinition = vdTypeDecl; } - if (!inClassTypeDef && currScope->findVarDecl(vd.getIdentifier())) + if (currScope->findVarDecl(vd.getIdentifier(), vd.getptr())) return error("Name Analysis", "Attempted to declare a Variable with an identifier that is " "already in use: " + vd.getIdentifier()->toString(), atl::static_pointer_cast(vd.getptr())); - if (!inClassTypeDef) - currScope->insertDecl(vd.getptr()); - return atl::shared_ptr(new BaseType(PrimitiveType::NULLPTR_T)); } atl::shared_ptr SemanticAnalysis::visit(VarDef &vd) { if (vd.type->astClass() == "ClassType") { - const atl::shared_ptr vdTypeDecl = - currScope->findClassDef(vd.getIdentifier()); - - if (vdTypeDecl == nullptr) + const atl::shared_ptr vdClassType = vd.type->accept(*this); + if (vdClassType->typeDefinition == nullptr) return error("Type Analysis", "Attempted to define variable with undefined class type.", atl::static_pointer_cast(vd.getptr())); } - if (currScope->findVarDecl(vd.getIdentifier())) + if (currScope->findVarDecl(vd.getIdentifier(), vd.getptr())) return error("Name Analysis", "Attempted to define a Variable with an identifier that is " "already in use: " + vd.getIdentifier()->toString(), atl::static_pointer_cast(vd.getptr())); - if (!inClassTypeDef) - currScope->insertDecl(vd.getptr()); + // Visit the value initialised. + const atl::shared_ptr valueType = vd.varValue->accept(*this); + if (*valueType != *vd.type) + return error("Type Analysis", "VarDef has mismatched types.", + atl::static_pointer_cast(vd.getptr())); return atl::shared_ptr(new BaseType(PrimitiveType::NULLPTR_T)); } @@ -654,7 +640,7 @@ atl::shared_ptr SemanticAnalysis::visit(VarExpr &ve) { ve.varIdentifier->toString(), ve.getptr()); ve.varDecl = varDecl; - return varDecl->type->accept(*this); + return varDecl->type; } atl::shared_ptr SemanticAnalysis::visit(While &w) { atl::shared_ptr conditionType = w.condition->accept(*this); @@ -671,4 +657,13 @@ atl::shared_ptr SemanticAnalysis::visit(While &w) { w.condition); w.body->accept(*this); return atl::shared_ptr(new BaseType(PrimitiveType::NULLPTR_T)); -} \ No newline at end of file +} +atl::shared_ptr +SemanticAnalysis::collapseReferenceTypes(atl::shared_ptr type) { + if (type->astClass() == "ReferenceType") { + type = atl::static_pointer_cast(type)->referencedType; + if (type->astClass() == "ReferenceType") + type = atl::static_pointer_cast(type)->referencedType; + } + return type; +} diff --git a/src/passes/SourceOutput.cpp b/src/passes/SourceOutput.cpp index d95d4bd..4352d91 100644 --- a/src/passes/SourceOutput.cpp +++ b/src/passes/SourceOutput.cpp @@ -33,10 +33,6 @@ atl::string SourceOutput::visit(Allocation &a) { return output; } -atl::string SourceOutput::visit(ArrayAccess &aa) { - atl::string output; - return output; -} atl::string SourceOutput::visit(ArrayType &at) { atl::string output = at.pointedType->accept(*this); output += "["; @@ -172,6 +168,17 @@ atl::string SourceOutput::visit(ClassTypeDef &ctd) { output += "\n};"; return output; } +atl::string SourceOutput::visit(ConstructorCall &cc) { + atl::string output = cc.constructorIdentifier->toString() + "("; + for (unsigned int i = 0; i < cc.constructorArgs.size(); ++i) { + atl::string currParam = cc.constructorArgs[i]->accept(*this); + if (i != (cc.constructorArgs.size() - 1)) + currParam += ", "; + output += currParam; + } + output += ")"; + return output; +} atl::string SourceOutput::visit(ConstructorDecl &cd) { atl::string output = cd.classType->accept(*this); output += "("; @@ -363,6 +370,9 @@ atl::string SourceOutput::visit(SizeOf &so) { return output; } atl::string SourceOutput::visit(StringLiteral &sl) { return sl.getLiteral(); } +atl::string SourceOutput::visit(SubscriptOp &so) { + return so.variable->accept(*this) + "[" + so.index->accept(*this) + "]"; +} atl::string SourceOutput::visit(TertiaryExpr &t) { atl::string output; output += t.tertiaryCondition->accept(*this); diff --git a/src/targets/GenerateX86.cpp b/src/targets/GenerateX86.cpp index 98edbcf..65adc14 100644 --- a/src/targets/GenerateX86.cpp +++ b/src/targets/GenerateX86.cpp @@ -32,10 +32,6 @@ atl::shared_ptr GenerateX86::visit(AddressOf &ao) { atl::shared_ptr GenerateX86::visit(Allocation &a) { return atl::make_shared(); } -atl::shared_ptr GenerateX86::visit(ArrayAccess &aa) { - aa.array->accept(*this); - return atl::make_shared(); -} atl::shared_ptr GenerateX86::visit(ArrayType &at) { return atl::make_shared(); } @@ -104,6 +100,15 @@ atl::shared_ptr GenerateX86::visit(ClassTypeDecl &ctd) { atl::shared_ptr GenerateX86::visit(ClassTypeDef &ctd) { return atl::make_shared(); } +atl::shared_ptr GenerateX86::visit(ConstructorCall &cc) { + for (int idx = cc.constructorArgs.size() - 1; idx >= 0; --idx) { + atl::shared_ptr argReg = + cc.constructorArgs[idx]->accept(*this); + // x86.push(argReg); + } + x86.call(cc.constructorIdentifier->toString()); + return X86::eax; +} atl::shared_ptr GenerateX86::visit(ConstructorDecl &cd) { return atl::make_shared(); } @@ -268,7 +273,7 @@ atl::shared_ptr GenerateX86::visit(PrefixOp &po) { return atl::make_shared(); } atl::shared_ptr GenerateX86::visit(Program &p) { - currScope = p.globalScope; + currScope = p.getptr(); x86.write("SECTION .data"); for (unsigned int idx = 0; idx < p.globalVars.size(); ++idx) { @@ -305,6 +310,10 @@ atl::shared_ptr GenerateX86::visit(SizeOf &so) { atl::shared_ptr GenerateX86::visit(StringLiteral &sl) { return atl::make_shared(); } + +atl::shared_ptr GenerateX86::visit(SubscriptOp &so) { + return atl::make_shared(); +} atl::shared_ptr GenerateX86::visit(TertiaryExpr &t) { return atl::make_shared(); } diff --git a/test/Test_AST.cpp b/test/Test_AST.cpp index ab8881e..bfd7779 100644 --- a/test/Test_AST.cpp +++ b/test/Test_AST.cpp @@ -281,64 +281,67 @@ TEST(ASTTest, FunDeclFunDefComparisons) { } TEST(ASTTest, Scope_resolveVarExpr_currScope) { - atl::shared_ptr outerScope(new Scope()); - atl::shared_ptr currScope(new Scope()); - currScope->outerScope = outerScope; - - /* Store a variable in the current scope. */ - const atl::shared_ptr varDeclType(new BaseType(PrimitiveType::INT)); - const atl::shared_ptr varDeclIdent(new Identifier("var1")); - const atl::shared_ptr varDecl( - new VarDecl(varDeclType, varDeclIdent)); - currScope->insertDecl(varDecl); - - /* Resolve it */ - const atl::shared_ptr searchIdent(new Identifier("var1")); - atl::shared_ptr resolvedVarDecl = - currScope->resolveVarExpr(searchIdent); - ASSERT_EQ(*varDecl, *resolvedVarDecl); + // atl::shared_ptr outerScope(new Scope()); + // atl::shared_ptr currScope(new Scope()); + // currScope->outerScope = outerScope; + + // /* Store a variable in the current scope. */ + // const atl::shared_ptr varDeclType(new + // BaseType(PrimitiveType::INT)); const atl::shared_ptr + // varDeclIdent(new Identifier("var1")); const atl::shared_ptr + // varDecl( + // new VarDecl(varDeclType, varDeclIdent)); + // currScope->insertDecl(varDecl); + + // /* Resolve it */ + // const atl::shared_ptr searchIdent(new Identifier("var1")); + // atl::shared_ptr resolvedVarDecl = + // currScope->resolveVarExpr(searchIdent); + // ASSERT_EQ(*varDecl, *resolvedVarDecl); } TEST(ASTTest, Scope_resolveVarExpr_outerScope) { - atl::shared_ptr outerScope(new Scope()); - atl::shared_ptr currScope(new Scope()); - currScope->outerScope = outerScope; - - /* Store a variable in the current scope. */ - const atl::shared_ptr varDeclType(new BaseType(PrimitiveType::INT)); - const atl::shared_ptr varDeclIdent(new Identifier("var1")); - const atl::shared_ptr varDecl( - new VarDecl(varDeclType, varDeclIdent)); - outerScope->insertDecl(varDecl); - - /* Resolve it */ - const atl::shared_ptr searchIdent(new Identifier("var1")); - atl::shared_ptr resolvedVarDecl = - currScope->resolveVarExpr(searchIdent); - ASSERT_EQ(*varDecl, *resolvedVarDecl); + // atl::shared_ptr outerScope(new Scope()); + // atl::shared_ptr currScope(new Scope()); + // currScope->outerScope = outerScope; + + // /* Store a variable in the current scope. */ + // const atl::shared_ptr varDeclType(new + // BaseType(PrimitiveType::INT)); const atl::shared_ptr + // varDeclIdent(new Identifier("var1")); const atl::shared_ptr + // varDecl( + // new VarDecl(varDeclType, varDeclIdent)); + // outerScope->insertDecl(varDecl); + + // /* Resolve it */ + // const atl::shared_ptr searchIdent(new Identifier("var1")); + // atl::shared_ptr resolvedVarDecl = + // currScope->resolveVarExpr(searchIdent); + // ASSERT_EQ(*varDecl, *resolvedVarDecl); } TEST(ASTTest, Scope_resolveFunCall_innerScope) { - atl::shared_ptr outerScope(new Scope()); - atl::shared_ptr currScope(new Scope()); - currScope->outerScope = outerScope; - - /* Store a function in the current scope. */ - const atl::shared_ptr funDeclOne(new FunDecl( - atl::set(), - atl::shared_ptr(new Identifier("myFunc")), - {atl::make_shared( - VarDecl(atl::make_shared(BaseType(PrimitiveType::CHAR)), - atl::shared_ptr(new Identifier("paramOne"))))}, - atl::make_shared(BaseType(PrimitiveType::VOID)))); - - currScope->insertDecl(funDeclOne); - - /* Resolve it */ - const atl::string funSignature = "myFunc(char)"; - atl::shared_ptr resolvedFunDecl = - currScope->resolveFunCall(funSignature); - ASSERT_EQ(*funDeclOne, *resolvedFunDecl); + // atl::shared_ptr outerScope(new Scope()); + // atl::shared_ptr currScope(new Scope()); + // currScope->outerScope = outerScope; + + // /* Store a function in the current scope. */ + // const atl::shared_ptr funDeclOne(new FunDecl( + // atl::set(), + // atl::shared_ptr(new Identifier("myFunc")), + // {atl::make_shared( + // VarDecl(atl::make_shared(BaseType(PrimitiveType::CHAR)), + // atl::shared_ptr(new + // Identifier("paramOne"))))}, + // atl::make_shared(BaseType(PrimitiveType::VOID)))); + + // currScope->insertDecl(funDeclOne); + + // /* Resolve it */ + // const atl::string funSignature = "myFunc(char)"; + // atl::shared_ptr resolvedFunDecl = + // currScope->resolveFunCall(funSignature); + // ASSERT_EQ(*funDeclOne, *resolvedFunDecl); } TEST(ASTTest, ClassTypeDef_resolveVarExpr) { @@ -353,7 +356,7 @@ TEST(ASTTest, ClassTypeDef_resolveVarExpr) { /* Resolve it */ const atl::shared_ptr searchIdent(new Identifier("memberVar")); atl::shared_ptr resolvedVarDecl = - classTypeDef->resolveVarExpr(searchIdent); + classTypeDef->findVarDecl(searchIdent); ASSERT_EQ(resolvedVarDecl.get(), classTypeDef->classDecls[0].get()); } diff --git a/test/Test_ASTAnalysis.cpp b/test/Test_ASTAnalysis.cpp index aeeebf9..3ec2638 100644 --- a/test/Test_ASTAnalysis.cpp +++ b/test/Test_ASTAnalysis.cpp @@ -16,6 +16,8 @@ using namespace ACC; // "test/tests/Test_ASTAnalysis/"; atl::string test_prefix = "../../test/tests/Test_ASTAnalysis/"; +// TODO: Test accessing namespace'd classes. + TEST(Test_ASTAnalysis, AmbiguousIdentifier) { const SourceHandler src(SourceHandler::Type::FILEPATH, test_prefix + "AmbiguousIdentifier/test.cpp"); @@ -62,6 +64,22 @@ TEST(Test_ASTAnalysis, DuplicateFunction) { ASSERT_EQ(0, semanticAnalysis.errorCount); } +TEST(Test_ASTAnalysis, DuplicateVariable) { + const SourceHandler src(SourceHandler::Type::FILEPATH, + test_prefix + "DuplicateVariable/test.cpp"); + ACC::Preprocessor preprocessor(src, {}); + ACC::Scanner scanner(preprocessor.getSource()); + Lexer lexer(scanner); + Parser parser(lexer); + + atl::shared_ptr progAST = parser.getAST(); + + SemanticAnalysis semanticAnalysis(progAST); + semanticAnalysis.run(); + semanticAnalysis.printErrors(); + ASSERT_NE(0, semanticAnalysis.errorCount); +} + TEST(Test_ASTAnalysis, MemberAccesses) { const SourceHandler src(SourceHandler::Type::FILEPATH, test_prefix + "MemberAccesses/test.cpp"); @@ -94,9 +112,9 @@ TEST(Test_ASTAnalysis, MemberCalls) { ASSERT_EQ(0, semanticAnalysis.errorCount); } -TEST(Test_ASTAnalysis, DuplicateVariable) { +TEST(Test_ASTAnalysis, NameAnalysis) { const SourceHandler src(SourceHandler::Type::FILEPATH, - test_prefix + "DuplicateVariable/test.cpp"); + test_prefix + "NameAnalysis/test.cpp"); ACC::Preprocessor preprocessor(src, {}); ACC::Scanner scanner(preprocessor.getSource()); Lexer lexer(scanner); @@ -107,12 +125,12 @@ TEST(Test_ASTAnalysis, DuplicateVariable) { SemanticAnalysis semanticAnalysis(progAST); semanticAnalysis.run(); semanticAnalysis.printErrors(); - ASSERT_NE(0, semanticAnalysis.errorCount); + ASSERT_EQ(0, semanticAnalysis.errorCount); } -TEST(Test_ASTAnalysis, NameAnalysis) { +TEST(Test_ASTAnalysis, NamespaceFunction) { const SourceHandler src(SourceHandler::Type::FILEPATH, - test_prefix + "NameAnalysis/test.cpp"); + test_prefix + "NamespaceFunction/test.cpp"); ACC::Preprocessor preprocessor(src, {}); ACC::Scanner scanner(preprocessor.getSource()); Lexer lexer(scanner); @@ -158,6 +176,22 @@ TEST(Test_ASTAnalysis, StringClass) { ASSERT_EQ(0, semanticAnalysis.errorCount); } +TEST(Test_ASTAnalysis, SubscriptResolution) { + const SourceHandler src(SourceHandler::Type::FILEPATH, + test_prefix + "SubscriptResolution/test.cpp"); + ACC::Preprocessor preprocessor(src, {}); + ACC::Scanner scanner(preprocessor.getSource()); + Lexer lexer(scanner); + Parser parser(lexer); + + atl::shared_ptr progAST = parser.getAST(); + + SemanticAnalysis semanticAnalysis(progAST); + semanticAnalysis.run(); + semanticAnalysis.printErrors(); + ASSERT_EQ(0, semanticAnalysis.errorCount); +} + TEST(Test_ASTAnalysis, UndefinedClass) { const SourceHandler src(SourceHandler::Type::FILEPATH, test_prefix + "UndefinedClass/test.cpp"); @@ -206,6 +240,22 @@ TEST(Test_ASTAnalysis, UndefinedVariable) { ASSERT_NE(0, semanticAnalysis.errorCount); } +TEST(Test_ASTAnalysis, UseBeforeDecl) { + const SourceHandler src(SourceHandler::Type::FILEPATH, + test_prefix + "UseBeforeDecl/test.cpp"); + ACC::Preprocessor preprocessor(src, {}); + ACC::Scanner scanner(preprocessor.getSource()); + Lexer lexer(scanner); + Parser parser(lexer); + + atl::shared_ptr progAST = parser.getAST(); + + SemanticAnalysis semanticAnalysis(progAST); + semanticAnalysis.run(); + semanticAnalysis.printErrors(); + ASSERT_NE(0, semanticAnalysis.errorCount); +} + // The fixture for testing class Project1. From google test primer. class Test_ASTAnalysis : public ::testing::Test { protected: diff --git a/test/Test_Parser.cpp b/test/Test_Parser.cpp index b8c8284..0ae7411 100644 --- a/test/Test_Parser.cpp +++ b/test/Test_Parser.cpp @@ -1,5 +1,6 @@ #include "gtest/gtest.h" +#include "AST.h" #include "Error.h" #include "Parser.h" #include "Preprocessor.h" @@ -9,7 +10,8 @@ using namespace ACC; // atl::string test_prefix = -// "/Users/alexanderwilson/Documents/GitHub/c-bootstrap/test/tests/Test_Parser/"; +// "/Users/alexanderwilson/Documents/GitHub/c-bootstrap/" +// "test/tests/Test_Parser/"; atl::string test_prefix = "../../test/tests/Test_Parser/"; TEST(Test_Parser, BinOp) { @@ -180,6 +182,55 @@ TEST(Test_Parser, InvalidSignatureFunDef) { ASSERT_TRUE(false); } +TEST(Test_Parser, SubscriptOp) { + const SourceHandler src(SourceHandler::Type::FILEPATH, + test_prefix + "SubscriptOp/test.cpp"); + ACC::Preprocessor preprocessor(src, {}); + ACC::Scanner scanner(preprocessor.getSource()); + ACC::Lexer lexer(scanner); + ACC::Parser parser(lexer); + atl::shared_ptr actual = parser.getAST(); + + // atl::set mainModifiers; + // atl::vector> expectedDecls = { + // atl::shared_ptr(new FunDef( + // mainModifiers, atl::shared_ptr(new + // Identifier("main")), + // {}, atl::shared_ptr(new BaseType(PrimitiveType::INT)), + // atl::shared_ptr(new Block( + // {atl::shared_ptr(new VarDef( + // atl::shared_ptr( + // new PointerType(atl::shared_ptr( + // new BaseType(PrimitiveType::INT)))), + // atl::shared_ptr(new Identifier("x")), + // atl::shared_ptr( + // new Allocation(atl::shared_ptr( + // new ArrayType(atl::shared_ptr( + // new + // BaseType(PrimitiveType::INT)), + // atl::shared_ptr( + // new IntLiteral("5")))))))), + // atl::shared_ptr(new VarDef( + // atl::shared_ptr( + // new PointerType(atl::shared_ptr( + // new BaseType(PrimitiveType::INT)))), + // atl::shared_ptr(new Identifier("y")), + // atl::shared_ptr(new SubscriptOp( + // atl::shared_ptr(new VarExpr( + // atl::shared_ptr(new + // Identifier("x")))), + // atl::shared_ptr(new + // IntLiteral("4")))))), + // atl::shared_ptr(new Return( + // atl::shared_ptr(new + // IntLiteral("1"))))}))))}; + + // ASSERT_EQ(actual->decls.size(), expectedDecls.size()); + + // for (unsigned int i = 0; i < expectedDecls.size(); ++i) + // ASSERT_TRUE(*actual->decls[i] == *expectedDecls[i]); +} + TEST(Test_Parser, VarDecls) { const SourceHandler src(SourceHandler::Type::FILEPATH, test_prefix + "VarDecls/test.cpp"); diff --git a/test/tests/Test_ASTAnalysis/MemberCalls/test.cpp b/test/tests/Test_ASTAnalysis/MemberCalls/test.cpp index 36b9d40..773e87c 100644 --- a/test/tests/Test_ASTAnalysis/MemberCalls/test.cpp +++ b/test/tests/Test_ASTAnalysis/MemberCalls/test.cpp @@ -1,20 +1,18 @@ -class Base { +class ClassOne { public: - int b_func() { return 1; } + int one_func() { return 1; } }; -class Derived { +class ClassTwo { public: - char m_int; - - Base d_func() { - Base b; - const int unused = this->m_int; - return b; + ClassOne two_func() { + ClassOne obj; + return obj; } }; int main() { - Derived myDerived; - int m_int = myDerived.d_func().b_func(); + ClassTwo myObj; + int val = myObj.two_func().one_func(); + return val; } diff --git a/test/tests/Test_ASTAnalysis/NamespaceFunction/test.cpp b/test/tests/Test_ASTAnalysis/NamespaceFunction/test.cpp new file mode 100644 index 0000000..89a1678 --- /dev/null +++ b/test/tests/Test_ASTAnalysis/NamespaceFunction/test.cpp @@ -0,0 +1,18 @@ + +namespace MyNamespace { +namespace Nested { +char namespacedFunc(char c) { return 2; } +} // namespace Nested +} // namespace MyNamespace + +namespace MyNamespace { +int namespacedFunc(int x) { return 1; } +} // namespace MyNamespace + +int main(int argc, char **argv) { + int foo; + foo = MyNamespace::namespacedFunc(1); + char c; + c = MyNamespace::Nested::namespacedFunc('a'); + return 1; +} diff --git a/test/tests/Test_ASTAnalysis/SubscriptResolution/test.cpp b/test/tests/Test_ASTAnalysis/SubscriptResolution/test.cpp new file mode 100644 index 0000000..6886f08 --- /dev/null +++ b/test/tests/Test_ASTAnalysis/SubscriptResolution/test.cpp @@ -0,0 +1,16 @@ + +class SubscriptExample { +public: + SubscriptExample(int x) : m_val(x) {} + + int operator[](const int y) { return m_val + y; } + +private: + int m_val; +}; + +int main(int argc, char **argv) { + SubscriptExample se(5); + int foo = se[1]; + return 1; +} diff --git a/test/tests/Test_ASTAnalysis/UseBeforeDecl/test.cpp b/test/tests/Test_ASTAnalysis/UseBeforeDecl/test.cpp new file mode 100644 index 0000000..5f79349 --- /dev/null +++ b/test/tests/Test_ASTAnalysis/UseBeforeDecl/test.cpp @@ -0,0 +1,5 @@ +int main(int argc, char **argv) { + myvar = 1; + int myvar; + return myvar; +} diff --git a/test/tests/Test_CodeGeneration/X86_SimpleFuncs/test.cpp b/test/tests/Test_CodeGeneration/X86_SimpleFuncs/test.cpp index 5962b01..c975056 100644 --- a/test/tests/Test_CodeGeneration/X86_SimpleFuncs/test.cpp +++ b/test/tests/Test_CodeGeneration/X86_SimpleFuncs/test.cpp @@ -2,7 +2,7 @@ int myGlobalInt; int ten() { int x; - x = 2 * (3 + 0x0f); + x = 2 * (3 + 15); return x; } diff --git a/test/tests/Test_Optimiser/FunDecls/test.cpp b/test/tests/Test_Optimiser/FunDecls/test.cpp index 5962b01..c975056 100644 --- a/test/tests/Test_Optimiser/FunDecls/test.cpp +++ b/test/tests/Test_Optimiser/FunDecls/test.cpp @@ -2,7 +2,7 @@ int myGlobalInt; int ten() { int x; - x = 2 * (3 + 0x0f); + x = 2 * (3 + 15); return x; } diff --git a/test/tests/Test_Parser/BinOp/test.cpp b/test/tests/Test_Parser/BinOp/test.cpp index 804a9ab..bb04295 100644 --- a/test/tests/Test_Parser/BinOp/test.cpp +++ b/test/tests/Test_Parser/BinOp/test.cpp @@ -5,6 +5,6 @@ static bool isalpha(const char c) { int main() { int y = 5; int x; - x = 1 + 0x2; + x = 1 + 2; return x; } diff --git a/test/tests/Test_Parser/ComplexBinOp/test.cpp b/test/tests/Test_Parser/ComplexBinOp/test.cpp index 479e4d2..e051aa3 100644 --- a/test/tests/Test_Parser/ComplexBinOp/test.cpp +++ b/test/tests/Test_Parser/ComplexBinOp/test.cpp @@ -2,7 +2,7 @@ int myGlobalInt; int ten() { int x; - x = 2 * (3 + 0x0f); + x = 2 * (3 + 15); return x; } diff --git a/test/tests/Test_Parser/SubscriptOp/test.cpp b/test/tests/Test_Parser/SubscriptOp/test.cpp new file mode 100644 index 0000000..cc46ead --- /dev/null +++ b/test/tests/Test_Parser/SubscriptOp/test.cpp @@ -0,0 +1,4 @@ +int main() { + int y = x[4]; + return 1; +}