aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPhilip Herron <herron.philip@googlemail.com>2020-05-27 19:05:17 +0100
committerPhilip Herron <philip.herron@embecosm.com>2020-11-28 21:13:15 +0000
commitab24b0549e3c0b358875d86c7528f301ddcc0e49 (patch)
tree553d8258f093e7ec9b9c03728ed718373e3dc33e /gcc
parent6f772d22974d1985f0de002437938480f60f01d7 (diff)
downloadgcc-ab24b0549e3c0b358875d86c7528f301ddcc0e49.zip
gcc-ab24b0549e3c0b358875d86c7528f301ddcc0e49.tar.gz
gcc-ab24b0549e3c0b358875d86c7528f301ddcc0e49.tar.bz2
Fix up returns and call expressions to actually work
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/backend/cscope.h30
-rw-r--r--gcc/rust/backend/rust-compile.cc167
2 files changed, 165 insertions, 32 deletions
diff --git a/gcc/rust/backend/cscope.h b/gcc/rust/backend/cscope.h
index 0cc0694..d759ffc 100644
--- a/gcc/rust/backend/cscope.h
+++ b/gcc/rust/backend/cscope.h
@@ -28,21 +28,39 @@ public:
types.Pop ();
}
- void PushCurrentFunction (std::string name, Bfunction *fn)
+ void PushCurrentFunction (std::string name, Bfunction *fn, Btype *retType,
+ Bvariable *retDecl)
{
- InsertFunction (name, fn);
fns.push_back (fn);
+ fnRetType.push_back (retType);
+ fnRetDecl.push_back (retDecl);
}
Bfunction *PopCurrentFunction ()
{
auto ret = fns.back ();
fns.pop_back ();
+ fnRetType.pop_back ();
+ fnRetDecl.pop_back ();
return ret;
}
Bfunction *GetCurrentFndecl () { return fns.back (); }
+ Btype *GetCurrentFnRetType () { return fnRetType.back (); }
+
+ Bvariable *GetCurrentFnRetDecl () { return fnRetDecl.back (); }
+
+ Btype *GetFnRetType (Bfunction *fn)
+ {
+ auto it = fnRetTypeMapping.find (fn);
+ if (it == fnRetTypeMapping.end ())
+ {
+ return NULL;
+ }
+ return it->second;
+ }
+
void PushBlock (Bblock *block)
{
blocks.push_back (block);
@@ -63,11 +81,14 @@ public:
return ret;
}
+ Bblock *CurBlock () { return blocks.back (); }
+
void AddStatement (Bstatement *stmt) { context.back ().push_back (stmt); }
- void InsertFunction (std::string name, Bfunction *fn)
+ void InsertFunction (std::string name, Bfunction *fn, Btype *retType)
{
fndecls.Insert (name, fn);
+ fnRetTypeMapping[fn] = retType;
}
bool LookupFunction (std::string name, Bfunction **fn)
@@ -95,6 +116,9 @@ private:
::std::vector<Bfunction *> fns;
::std::vector<Bblock *> blocks;
::std::vector< ::std::vector<Bstatement *> > context;
+ ::std::vector< ::Btype *> fnRetType;
+ ::std::vector< ::Bvariable *> fnRetDecl;
+ ::std::map<Bfunction *, Btype *> fnRetTypeMapping;
Analysis::Scope<Bfunction *> fndecls;
Analysis::Scope<Bvariable *> vars;
diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc
index 04f33e9..480fa9f 100644
--- a/gcc/rust/backend/rust-compile.cc
+++ b/gcc/rust/backend/rust-compile.cc
@@ -35,17 +35,41 @@ Compilation::go ()
scope.Push ();
// builtin primitives
- scope.InsertType ("i64", backend->integer_type (false, 64));
- scope.InsertType ("i32", backend->integer_type (false, 32));
- scope.InsertType ("i16", backend->integer_type (false, 16));
- scope.InsertType ("i8", backend->integer_type (false, 8));
- scope.InsertType ("u64", backend->integer_type (true, 64));
- scope.InsertType ("u32", backend->integer_type (true, 32));
- scope.InsertType ("u16", backend->integer_type (true, 16));
- scope.InsertType ("u8", backend->integer_type (true, 8));
+ scope.InsertType ("bool",
+ backend->named_type ("bool", backend->bool_type (),
+ Linemap::predeclared_location ()));
+ scope.InsertType ("i64",
+ backend->named_type ("i64",
+ backend->integer_type (false, 64),
+ Linemap::predeclared_location ()));
+ scope.InsertType ("i32",
+ backend->named_type ("i32",
+ backend->integer_type (false, 32),
+ Linemap::predeclared_location ()));
+ scope.InsertType ("i16",
+ backend->named_type ("i16",
+ backend->integer_type (false, 16),
+ Linemap::predeclared_location ()));
+ scope.InsertType ("i8",
+ backend->named_type ("i8", backend->integer_type (false, 8),
+ Linemap::predeclared_location ()));
+ scope.InsertType ("u64",
+ backend->named_type ("u64",
+ backend->integer_type (true, 64),
+ Linemap::predeclared_location ()));
+ scope.InsertType ("u32",
+ backend->named_type ("u32",
+ backend->integer_type (true, 32),
+ Linemap::predeclared_location ()));
+ scope.InsertType ("u16",
+ backend->named_type ("u16",
+ backend->integer_type (true, 16),
+ Linemap::predeclared_location ()));
+ scope.InsertType ("u8",
+ backend->named_type ("u8", backend->integer_type (true, 8),
+ Linemap::predeclared_location ()));
scope.InsertType ("f64", backend->float_type (64));
scope.InsertType ("f32", backend->float_type (32));
- scope.InsertType ("bool", backend->bool_type ());
for (auto &item : crate.items)
item->accept_vis (*this);
@@ -178,6 +202,7 @@ Compilation::visit (AST::PathInExpression &path)
auto expr
= backend->function_code_expression (fn, path.get_locus_slow ());
exprs.push_back (expr);
+ translatedType = scope.GetFnRetType (fn);
return;
}
}
@@ -293,11 +318,35 @@ Compilation::visit (AST::ArithmeticOrLogicalExpr &expr)
case AST::ArithmeticOrLogicalExpr::ADD:
op = OPERATOR_PLUS;
break;
-
- // TODO fill in the other operators
-
+ case AST::ArithmeticOrLogicalExpr::SUBTRACT:
+ op = OPERATOR_MINUS;
+ break;
+ case AST::ArithmeticOrLogicalExpr::MULTIPLY:
+ op = OPERATOR_MULT;
+ break;
+ case AST::ArithmeticOrLogicalExpr::DIVIDE:
+ op = OPERATOR_DIV;
+ break;
+ case AST::ArithmeticOrLogicalExpr::MODULUS:
+ op = OPERATOR_MOD;
+ break;
+ case AST::ArithmeticOrLogicalExpr::BITWISE_AND:
+ op = OPERATOR_AND;
+ break;
+ case AST::ArithmeticOrLogicalExpr::BITWISE_OR:
+ op = OPERATOR_OR;
+ break;
+ case AST::ArithmeticOrLogicalExpr::BITWISE_XOR:
+ op = OPERATOR_XOR;
+ break;
+ case AST::ArithmeticOrLogicalExpr::LEFT_SHIFT:
+ op = OPERATOR_LSHIFT;
+ break;
+ case AST::ArithmeticOrLogicalExpr::RIGHT_SHIFT:
+ op = OPERATOR_RSHIFT;
+ break;
default:
- rust_error_at (expr.get_locus_slow (), "failed to compile expression");
+ rust_fatal_error (expr.get_locus_slow (), "failed to compile operator");
return;
}
@@ -414,13 +463,14 @@ void
Compilation::visit (AST::CallExpr &expr)
{
Bexpression *fn = NULL;
+ translatedType = NULL;
VISIT_POP (expr.function->get_locus_slow (), expr.function, fn, exprs);
if (fn == NULL)
{
- printf ("expr.function = %s\n", expr.function->as_string ().c_str ());
rust_error_at (expr.function->get_locus_slow (), "failed to resolve");
return;
}
+ Btype *returnType = translatedType; // can be NULL
std::vector<Bexpression *> args;
for (auto &param : expr.params)
@@ -491,7 +541,8 @@ Compilation::visit (AST::ReturnExpr &expr)
VISIT_POP (expr.return_expr->get_locus_slow (), expr.return_expr, ret, exprs);
if (ret == NULL)
{
- rust_error_at (expr.return_expr->get_locus_slow (), "failed to compile");
+ rust_fatal_error (expr.return_expr->get_locus_slow (),
+ "failed to compile");
return;
}
@@ -505,42 +556,65 @@ Compilation::visit (AST::ReturnExpr &expr)
void
Compilation::visit (AST::UnsafeBlockExpr &expr)
{}
+
void
Compilation::visit (AST::LoopExpr &expr)
{}
+
void
Compilation::visit (AST::WhileLoopExpr &expr)
{}
+
void
Compilation::visit (AST::WhileLetLoopExpr &expr)
{}
void
Compilation::visit (AST::ForLoopExpr &expr)
{}
+
void
Compilation::visit (AST::IfExpr &expr)
-{}
+{
+ printf ("IfExpr %s\n", expr.as_string ().c_str ());
+}
void
Compilation::visit (AST::IfExprConseqElse &expr)
-{}
+{
+ printf ("IfExprConseqElse %s\n", expr.as_string ().c_str ());
+}
void
Compilation::visit (AST::IfExprConseqIf &expr)
-{}
+{
+ printf ("IfExprConseqIf %s\n", expr.as_string ().c_str ());
+}
void
Compilation::visit (AST::IfExprConseqIfLet &expr)
-{}
+{
+ printf ("IfExprConseqIfLet %s\n", expr.as_string ().c_str ());
+}
void
Compilation::visit (AST::IfLetExpr &expr)
-{}
+{
+ printf ("IfLetExpr %s\n", expr.as_string ().c_str ());
+}
void
Compilation::visit (AST::IfLetExprConseqElse &expr)
-{}
+{
+ printf ("IfLetExprConseqElse %s\n", expr.as_string ().c_str ());
+}
+
void
Compilation::visit (AST::IfLetExprConseqIf &expr)
-{}
+{
+ printf ("IfLetExprConseqIf %s\n", expr.as_string ().c_str ());
+}
+
void
Compilation::visit (AST::IfLetExprConseqIfLet &expr)
-{}
+{
+ printf ("IfLetExprConseqIfLet %s\n", expr.as_string ().c_str ());
+}
+
// void Compilation::visit(MatchCase& match_case) {}
void
Compilation::visit (AST::MatchCaseBlockExpr &match_case)
@@ -639,19 +713,24 @@ Compilation::visit (AST::Function &function)
function.return_type->accept_vis (*this);
if (translatedType == NULL)
{
- rust_error_at (function.locus,
- "failed to generate type for function");
+ rust_fatal_error (function.locus,
+ "failed to generate type for function");
return;
}
+ returnType = translatedType;
+
+ // add into the results:
+ results.push_back (
+ Backend::Btyped_identifier ("_", translatedType, Location ()));
}
- Btype *fntype = backend->function_type (receiver, parameters, results,
- returnType, function.locus);
+ Btype *fntype = backend->function_type (receiver, parameters, results, NULL,
+ function.locus);
Bfunction *fndecl
= backend->function (fntype, function.function_name, "" /* asm_name */,
0 /* flags */, function.locus);
- scope.PushCurrentFunction (function.function_name, fndecl);
+ scope.InsertFunction (function.function_name, fndecl, returnType);
scope.Push ();
// setup the params
@@ -695,8 +774,22 @@ Compilation::visit (AST::Function &function)
auto code_block = backend->block (fndecl, enclosingScope, vars,
start_location, end_location);
+
scope.PushBlock (code_block);
+ Bvariable *retDecl = NULL;
+ if (function.has_function_return_type ())
+ {
+ bool address_is_taken = false;
+ Bstatement *ret_var_stmt = NULL;
+ retDecl = backend->temporary_variable (fndecl, code_block, returnType,
+ NULL, address_is_taken,
+ function.locus, &ret_var_stmt);
+ scope.AddStatement (ret_var_stmt);
+ }
+ scope.PushCurrentFunction (function.function_name, fndecl, returnType,
+ retDecl);
+
for (auto &stmt : function.function_body->statements)
stmt->accept_vis (*this);
@@ -933,7 +1026,23 @@ Compilation::visit (AST::ExprStmtWithoutBlock &stmt)
void
Compilation::visit (AST::ExprStmtWithBlock &stmt)
{
- rust_fatal_error (stmt.get_locus_slow (), "need new block to continue");
+ printf ("ExprStmtWithBlock: %s\n", stmt.as_string ().c_str ());
+
+ Bblock *enclosingScope = NULL;
+ Location start_location; /* = stmt.locus; FIXME */
+ Location end_location; // FIXME
+
+ std::vector<Bvariable *> vars;
+ auto code_block
+ = backend->block (scope.GetCurrentFndecl (), scope.CurBlock (), vars,
+ start_location, end_location);
+
+ scope.PushBlock (code_block);
+ stmt.expr->accept_vis (*this);
+ scope.PopBlock ();
+
+ auto body = backend->block_statement (code_block);
+ scope.AddStatement (body);
}
// rust-type.h