Skip to content

Phil/compilation simple #24

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
May 17, 2020
1 change: 1 addition & 0 deletions gcc/rust/Make-lang.in
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ GRS_OBJS = \
rust/rust-ast-full-test.o \
rust/rust-session-manager.o \
rust/rust-resolution.o \
rust/rust-scan.o \
rust/rust-compile.o \
$(END)
# removed object files from here
Expand Down
122 changes: 92 additions & 30 deletions gcc/rust/analysis/rust-resolution.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
namespace Rust {
namespace Analysis {

TypeResolution::TypeResolution (AST::Crate &crate) : crate (crate)
TypeResolution::TypeResolution (AST::Crate &crate, TopLevelScan &toplevel)
: crate (crate), toplevel (toplevel)
{
typeScope.Push ();
scope.Push ();
Expand Down Expand Up @@ -50,9 +51,9 @@ TypeResolution::~TypeResolution ()
}

bool
TypeResolution::ResolveNamesAndTypes (AST::Crate &crate)
TypeResolution::ResolveNamesAndTypes (AST::Crate &crate, TopLevelScan &toplevel)
{
TypeResolution resolver (crate);
TypeResolution resolver (crate, toplevel);
return resolver.go ();
}

Expand All @@ -65,6 +66,30 @@ TypeResolution::go ()
return true;
}

bool
TypeResolution::typesAreCompatible (AST::Type *lhs, AST::Type *rhs,
Location locus)
{
lhs->accept_vis (*this);
rhs->accept_vis (*this);

auto rhsTypeStr = typeComparisonBuffer.back ();
typeComparisonBuffer.pop_back ();
auto lhsTypeStr = typeComparisonBuffer.back ();
typeComparisonBuffer.pop_back ();

// FIXME this needs to handle the cases of an i8 going into an i32 which is
// compatible
if (lhsTypeStr.compare (rhsTypeStr))
{
rust_error_at (locus, "E0308: expected: %s, found %s",
lhsTypeStr.c_str (), rhsTypeStr.c_str ());
return false;
}

return true;
}

void
TypeResolution::visit (AST::Token &tok)
{}
Expand Down Expand Up @@ -124,18 +149,21 @@ TypeResolution::visit (AST::TypePathSegmentFunction &segment)
void
TypeResolution::visit (AST::TypePath &path)
{
printf ("TypePath: %s\n", path.as_string ().c_str ());
// this may not be robust enough for type comparisons but lets try it for now
typeComparisonBuffer.push_back (path.as_string ());
}

void
TypeResolution::visit (AST::QualifiedPathInExpression &path)
{
printf ("QualifiedPathInExpression: %s\n", path.as_string ().c_str ());
typeComparisonBuffer.push_back (path.as_string ());
}

void
TypeResolution::visit (AST::QualifiedPathInType &path)
{}
{
typeComparisonBuffer.push_back (path.as_string ());
}

// rust-expr.h
void
Expand Down Expand Up @@ -245,7 +273,7 @@ TypeResolution::visit (AST::ArithmeticOrLogicalExpr &expr)
// scope will require knowledge of the type

// do the lhsType and the rhsType match
// TODO
typesAreCompatible (lhsType, rhsType, expr.right_expr->get_locus_slow ());
}

void
Expand All @@ -254,9 +282,7 @@ TypeResolution::visit (AST::ComparisonExpr &expr)

void
TypeResolution::visit (AST::LazyBooleanExpr &expr)
{
printf ("LazyBooleanExpr: %s\n", expr.as_string ().c_str ());
}
{}

void
TypeResolution::visit (AST::TypeCastExpr &expr)
Expand All @@ -265,14 +291,41 @@ TypeResolution::visit (AST::TypeCastExpr &expr)
void
TypeResolution::visit (AST::AssignmentExpr &expr)
{
printf ("AssignmentExpr: %s\n", expr.as_string ().c_str ());
size_t before;
before = typeBuffer.size ();
expr.visit_lhs (*this);
if (typeBuffer.size () <= before)
{
rust_error_at (expr.locus, "unable to determine lhs type");
return;
}

auto lhsType = typeBuffer.back ();
typeBuffer.pop_back ();

before = typeBuffer.size ();
expr.visit_rhs (*this);
if (typeBuffer.size () <= before)
{
rust_error_at (expr.locus, "unable to determine rhs type");
return;
}

auto rhsType = typeBuffer.back ();
// not poping because we will be checking they match and the
// scope will require knowledge of the type

// do the lhsType and the rhsType match
if (!typesAreCompatible (lhsType, rhsType,
expr.right_expr->get_locus_slow ()))
return;

// is the lhs mutable?
}

void
TypeResolution::visit (AST::CompoundAssignmentExpr &expr)
{
printf ("CompoundAssignmentExpr: %s\n", expr.as_string ().c_str ());
}
{}

void
TypeResolution::visit (AST::GroupedExpr &expr)
Expand Down Expand Up @@ -340,9 +393,13 @@ TypeResolution::visit (AST::EnumExprTuple &expr)
void
TypeResolution::visit (AST::EnumExprFieldless &expr)
{}

void
TypeResolution::visit (AST::CallExpr &expr)
{}
{
printf ("CallExpr: %s\n", expr.as_string ().c_str ());
}

void
TypeResolution::visit (AST::MethodCallExpr &expr)
{}
Expand Down Expand Up @@ -481,18 +538,25 @@ TypeResolution::visit (AST::UseDeclaration &use_decl)
void
TypeResolution::visit (AST::Function &function)
{
// always emit the function with return type in the event of nil return type
// its a marker for a void function
scope.Insert (function.function_name, function.return_type.get ());

scope.Push ();
printf ("INSIDE FUNCTION: %s\n", function.function_name.c_str ());

for (auto &param : function.function_params)
{
printf ("FUNC PARAM: %s\n", param.as_string ().c_str ());
}
auto before = letPatternBuffer.size ();
param.param_name->accept_vis (*this);
if (letPatternBuffer.size () <= before)
{
rust_error_at (param.locus, "failed to analyse parameter name");
return;
}

// ensure return types
// TODO
auto paramName = letPatternBuffer.back ();
letPatternBuffer.pop_back ();
scope.Insert (paramName.variable_ident, param.type.get ());
}

// walk the expression body
for (auto &stmt : function.function_body->statements)
Expand Down Expand Up @@ -713,8 +777,11 @@ TypeResolution::visit (AST::LetStmt &stmt)

if (stmt.has_type () && stmt.has_init_expr ())
{
auto declaredTyped = stmt.type.get ();
// TODO compare this type to the inferred type to ensure they match
if (!typesAreCompatible (stmt.type.get (), inferedType,
stmt.init_expr->get_locus_slow ()))
{
return;
}
}
else if (stmt.has_type () && !stmt.has_init_expr ())
{
Expand All @@ -727,8 +794,7 @@ TypeResolution::visit (AST::LetStmt &stmt)
// ensure the decl has the type set for compilation later on
if (!stmt.has_type ())
{
// FIXME
// stmt.type = inferedType;
stmt.inferedType = inferedType;
}

// get all the names part of this declaration and add the types to the scope
Expand All @@ -743,16 +809,12 @@ TypeResolution::visit (AST::LetStmt &stmt)
void
TypeResolution::visit (AST::ExprStmtWithoutBlock &stmt)
{
printf ("ExprStmtWithoutBlock: %s\n", stmt.as_string ().c_str ());
stmt.expr->accept_vis (*this);
}

void
TypeResolution::visit (AST::ExprStmtWithBlock &stmt)
{
printf ("ExprStmtWithBlock: %s\n", stmt.as_string ().c_str ());
stmt.expr->accept_vis (*this);
}
{}

// rust-type.h
void
Expand Down
13 changes: 9 additions & 4 deletions gcc/rust/analysis/rust-resolution.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "rust-system.h"
#include "rust-ast-full.h"
#include "rust-ast-visitor.h"
#include "rust-scan.h"
#include "scope.h"

namespace Rust {
Expand All @@ -11,7 +12,7 @@ namespace Analysis {
class TypeResolution : public AST::ASTVisitor
{
public:
static bool ResolveNamesAndTypes (AST::Crate &crate);
static bool ResolveNamesAndTypes (AST::Crate &crate, TopLevelScan &toplevel);

~TypeResolution ();

Expand Down Expand Up @@ -221,16 +222,20 @@ class TypeResolution : public AST::ASTVisitor
virtual void visit (AST::BareFunctionType &type);

private:
TypeResolution (AST::Crate &crate);
TypeResolution (AST::Crate &crate, TopLevelScan &toplevel);

bool go ();

Scope scope;
Scope typeScope;
bool typesAreCompatible (AST::Type *lhs, AST::Type *rhs, Location locus);

Scope<AST::Type *> scope;
Scope<AST::Type *> typeScope;
AST::Crate &crate;
TopLevelScan &toplevel;

std::vector<AST::IdentifierPattern> letPatternBuffer;
std::vector<AST::Type *> typeBuffer;
std::vector<std::string> typeComparisonBuffer;
};

} // namespace Analysis
Expand Down
Loading