mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 20:11:12 +01:00
Revert to handling Expression by const pointer (#616)
This reverts the bulk of #606, #607, and #611, as well as parts of #588, #605, and #614.
This commit is contained in:
@@ -22,7 +22,7 @@ void ChoiceDeclaration::Print() const {
|
||||
std::cout << "choice " << name << " {" << std::endl;
|
||||
for (const auto& [name, signature] : alternatives) {
|
||||
std::cout << "alt " << name << " ";
|
||||
PrintExp(&signature);
|
||||
PrintExp(signature);
|
||||
std::cout << ";" << std::endl;
|
||||
}
|
||||
std::cout << "}" << std::endl;
|
||||
|
||||
@@ -137,10 +137,11 @@ struct StructDeclaration {
|
||||
struct ChoiceDeclaration {
|
||||
int line_num;
|
||||
std::string name;
|
||||
std::list<std::pair<std::string, Expression>> alternatives;
|
||||
std::list<std::pair<std::string, const Expression*>> alternatives;
|
||||
|
||||
ChoiceDeclaration(int line_num, std::string name,
|
||||
std::list<std::pair<std::string, Expression>> alternatives)
|
||||
ChoiceDeclaration(
|
||||
int line_num, std::string name,
|
||||
std::list<std::pair<std::string, const Expression*>> alternatives)
|
||||
: line_num(line_num), name(name), alternatives(std::move(alternatives)) {}
|
||||
|
||||
void Print() const;
|
||||
|
||||
@@ -84,12 +84,11 @@ auto Expression::MakeContinuationType(int line_num) -> const Expression* {
|
||||
return type;
|
||||
}
|
||||
|
||||
auto Expression::MakeFunType(int line_num, Expression param, Expression ret)
|
||||
-> const Expression* {
|
||||
auto Expression::MakeFunType(int line_num, const Expression* param,
|
||||
const Expression* ret) -> const Expression* {
|
||||
auto* t = new Expression();
|
||||
t->line_num = line_num;
|
||||
t->value = FunctionType(
|
||||
{.parameter = std::move(param), .return_type = std::move(ret)});
|
||||
t->value = FunctionType({.parameter = param, .return_type = ret});
|
||||
return t;
|
||||
}
|
||||
|
||||
@@ -100,11 +99,11 @@ auto Expression::MakeVar(int line_num, std::string var) -> const Expression* {
|
||||
return v;
|
||||
}
|
||||
|
||||
auto Expression::MakeVarPat(int line_num, std::string var, Expression type)
|
||||
-> const Expression* {
|
||||
auto Expression::MakeVarPat(int line_num, std::string var,
|
||||
const Expression* type) -> const Expression* {
|
||||
auto* v = new Expression();
|
||||
v->line_num = line_num;
|
||||
v->value = PatternVariable({.name = std::move(var), .type = std::move(type)});
|
||||
v->value = PatternVariable({.name = std::move(var), .type = type});
|
||||
return v;
|
||||
}
|
||||
|
||||
@@ -123,35 +122,36 @@ auto Expression::MakeBool(int line_num, bool b) -> const Expression* {
|
||||
}
|
||||
|
||||
auto Expression::MakeOp(int line_num, enum Operator op,
|
||||
std::vector<Expression> args) -> const Expression* {
|
||||
std::vector<const Expression*> args)
|
||||
-> const Expression* {
|
||||
auto* e = new Expression();
|
||||
e->line_num = line_num;
|
||||
e->value = PrimitiveOperator({.op = op, .arguments = std::move(args)});
|
||||
return e;
|
||||
}
|
||||
|
||||
auto Expression::MakeUnOp(int line_num, enum Operator op, Expression arg)
|
||||
auto Expression::MakeUnOp(int line_num, enum Operator op, const Expression* arg)
|
||||
-> const Expression* {
|
||||
auto* e = new Expression();
|
||||
e->line_num = line_num;
|
||||
e->value = PrimitiveOperator({.op = op, .arguments = {std::move(arg)}});
|
||||
e->value = PrimitiveOperator({.op = op, .arguments = {arg}});
|
||||
return e;
|
||||
}
|
||||
|
||||
auto Expression::MakeBinOp(int line_num, enum Operator op, Expression arg1,
|
||||
Expression arg2) -> const Expression* {
|
||||
auto* e = new Expression();
|
||||
e->line_num = line_num;
|
||||
e->value = PrimitiveOperator(
|
||||
{.op = op, .arguments = {std::move(arg1), std::move(arg2)}});
|
||||
return e;
|
||||
}
|
||||
|
||||
auto Expression::MakeCall(int line_num, Expression fun, Expression arg)
|
||||
auto Expression::MakeBinOp(int line_num, enum Operator op,
|
||||
const Expression* arg1, const Expression* arg2)
|
||||
-> const Expression* {
|
||||
auto* e = new Expression();
|
||||
e->line_num = line_num;
|
||||
e->value = Call({.function = std::move(fun), .argument = std::move(arg)});
|
||||
e->value = PrimitiveOperator({.op = op, .arguments = {arg1, arg2}});
|
||||
return e;
|
||||
}
|
||||
|
||||
auto Expression::MakeCall(int line_num, const Expression* fun,
|
||||
const Expression* arg) -> const Expression* {
|
||||
auto* e = new Expression();
|
||||
e->line_num = line_num;
|
||||
e->value = Call({.function = fun, .argument = arg});
|
||||
return e;
|
||||
}
|
||||
|
||||
@@ -159,7 +159,7 @@ auto Expression::MakeGetField(int line_num, const Expression* exp,
|
||||
std::string field) -> const Expression* {
|
||||
auto* e = new Expression();
|
||||
e->line_num = line_num;
|
||||
e->value = FieldAccess({.aggregate = *exp, .field = std::move(field)});
|
||||
e->value = FieldAccess({.aggregate = exp, .field = std::move(field)});
|
||||
return e;
|
||||
}
|
||||
|
||||
@@ -187,11 +187,11 @@ auto Expression::MakeTuple(int line_num, std::vector<FieldInitializer> args)
|
||||
return e;
|
||||
}
|
||||
|
||||
auto Expression::MakeIndex(int line_num, Expression exp, Expression i)
|
||||
-> const Expression* {
|
||||
auto Expression::MakeIndex(int line_num, const Expression* exp,
|
||||
const Expression* i) -> const Expression* {
|
||||
auto* e = new Expression();
|
||||
e->line_num = line_num;
|
||||
e->value = Index({.aggregate = std::move(exp), .offset = std::move(i)});
|
||||
e->value = Index({.aggregate = exp, .offset = i});
|
||||
return e;
|
||||
}
|
||||
|
||||
@@ -231,20 +231,20 @@ static void PrintFields(const std::vector<FieldInitializer>& fields) {
|
||||
std::cout << ", ";
|
||||
}
|
||||
std::cout << iter->name << " = ";
|
||||
PrintExp(iter->expression.GetPointer());
|
||||
PrintExp(iter->expression);
|
||||
}
|
||||
}
|
||||
|
||||
void PrintExp(const Expression* e) {
|
||||
switch (e->tag()) {
|
||||
case ExpressionKind::Index:
|
||||
PrintExp(e->GetIndex().aggregate.GetPointer());
|
||||
PrintExp(e->GetIndex().aggregate);
|
||||
std::cout << "[";
|
||||
PrintExp(e->GetIndex().offset.GetPointer());
|
||||
PrintExp(e->GetIndex().offset);
|
||||
std::cout << "]";
|
||||
break;
|
||||
case ExpressionKind::GetField:
|
||||
PrintExp(e->GetFieldAccess().aggregate.GetPointer());
|
||||
PrintExp(e->GetFieldAccess().aggregate);
|
||||
std::cout << ".";
|
||||
std::cout << e->GetFieldAccess().field;
|
||||
break;
|
||||
@@ -269,15 +269,15 @@ void PrintExp(const Expression* e) {
|
||||
PrintOp(op.op);
|
||||
std::cout << " ";
|
||||
auto iter = op.arguments.begin();
|
||||
PrintExp(&*iter);
|
||||
PrintExp(*iter);
|
||||
} else if (op.arguments.size() == 2) {
|
||||
auto iter = op.arguments.begin();
|
||||
PrintExp(&*iter);
|
||||
PrintExp(*iter);
|
||||
std::cout << " ";
|
||||
PrintOp(op.op);
|
||||
std::cout << " ";
|
||||
++iter;
|
||||
PrintExp(&*iter);
|
||||
PrintExp(*iter);
|
||||
}
|
||||
std::cout << ")";
|
||||
break;
|
||||
@@ -286,17 +286,17 @@ void PrintExp(const Expression* e) {
|
||||
std::cout << e->GetVariable().name;
|
||||
break;
|
||||
case ExpressionKind::PatternVariable:
|
||||
PrintExp(e->GetPatternVariable().type.GetPointer());
|
||||
PrintExp(e->GetPatternVariable().type);
|
||||
std::cout << ": ";
|
||||
std::cout << e->GetPatternVariable().name;
|
||||
break;
|
||||
case ExpressionKind::Call:
|
||||
PrintExp(e->GetCall().function.GetPointer());
|
||||
PrintExp(e->GetCall().function);
|
||||
if (e->GetCall().argument->tag() == ExpressionKind::Tuple) {
|
||||
PrintExp(e->GetCall().argument.GetPointer());
|
||||
PrintExp(e->GetCall().argument);
|
||||
} else {
|
||||
std::cout << "(";
|
||||
PrintExp(e->GetCall().argument.GetPointer());
|
||||
PrintExp(e->GetCall().argument);
|
||||
std::cout << ")";
|
||||
}
|
||||
break;
|
||||
@@ -317,9 +317,9 @@ void PrintExp(const Expression* e) {
|
||||
break;
|
||||
case ExpressionKind::FunctionT:
|
||||
std::cout << "fn ";
|
||||
PrintExp(e->GetFunctionType().parameter.GetPointer());
|
||||
PrintExp(e->GetFunctionType().parameter);
|
||||
std::cout << " -> ";
|
||||
PrintExp(e->GetFunctionType().return_type.GetPointer());
|
||||
PrintExp(e->GetFunctionType().return_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
#include "common/indirect_value.h"
|
||||
|
||||
namespace Carbon {
|
||||
|
||||
struct Expression;
|
||||
@@ -21,7 +19,7 @@ struct FieldInitializer {
|
||||
std::string name;
|
||||
|
||||
// The expression that initializes the field.
|
||||
IndirectValue<Expression> expression;
|
||||
const Expression* expression;
|
||||
};
|
||||
|
||||
enum class ExpressionKind {
|
||||
@@ -64,20 +62,20 @@ struct Variable {
|
||||
|
||||
struct FieldAccess {
|
||||
static constexpr ExpressionKind Kind = ExpressionKind::GetField;
|
||||
IndirectValue<Expression> aggregate;
|
||||
const Expression* aggregate;
|
||||
std::string field;
|
||||
};
|
||||
|
||||
struct Index {
|
||||
static constexpr ExpressionKind Kind = ExpressionKind::Index;
|
||||
IndirectValue<Expression> aggregate;
|
||||
IndirectValue<Expression> offset;
|
||||
const Expression* aggregate;
|
||||
const Expression* offset;
|
||||
};
|
||||
|
||||
struct PatternVariable {
|
||||
static constexpr ExpressionKind Kind = ExpressionKind::PatternVariable;
|
||||
std::string name;
|
||||
IndirectValue<Expression> type;
|
||||
const Expression* type;
|
||||
};
|
||||
|
||||
struct IntLiteral {
|
||||
@@ -98,19 +96,19 @@ struct Tuple {
|
||||
struct PrimitiveOperator {
|
||||
static constexpr ExpressionKind Kind = ExpressionKind::PrimitiveOp;
|
||||
Operator op;
|
||||
std::vector<Expression> arguments;
|
||||
std::vector<const Expression*> arguments;
|
||||
};
|
||||
|
||||
struct Call {
|
||||
static constexpr ExpressionKind Kind = ExpressionKind::Call;
|
||||
IndirectValue<Expression> function;
|
||||
IndirectValue<Expression> argument;
|
||||
const Expression* function;
|
||||
const Expression* argument;
|
||||
};
|
||||
|
||||
struct FunctionType {
|
||||
static constexpr ExpressionKind Kind = ExpressionKind::FunctionT;
|
||||
IndirectValue<Expression> parameter;
|
||||
IndirectValue<Expression> return_type;
|
||||
const Expression* parameter;
|
||||
const Expression* return_type;
|
||||
};
|
||||
|
||||
struct AutoT {
|
||||
@@ -138,29 +136,29 @@ struct Expression {
|
||||
inline auto tag() const -> ExpressionKind;
|
||||
|
||||
static auto MakeVar(int line_num, std::string var) -> const Expression*;
|
||||
static auto MakeVarPat(int line_num, std::string var, Expression type)
|
||||
static auto MakeVarPat(int line_num, std::string var, const Expression* type)
|
||||
-> const Expression*;
|
||||
static auto MakeInt(int line_num, int i) -> const Expression*;
|
||||
static auto MakeBool(int line_num, bool b) -> const Expression*;
|
||||
static auto MakeOp(int line_num, Operator op, std::vector<Expression> args)
|
||||
-> const Expression*;
|
||||
static auto MakeUnOp(int line_num, enum Operator op, Expression arg)
|
||||
-> const Expression*;
|
||||
static auto MakeBinOp(int line_num, enum Operator op, Expression arg1,
|
||||
Expression arg2) -> const Expression*;
|
||||
static auto MakeCall(int line_num, Expression fun, Expression arg)
|
||||
static auto MakeOp(int line_num, Operator op,
|
||||
std::vector<const Expression*> args) -> const Expression*;
|
||||
static auto MakeUnOp(int line_num, enum Operator op, const Expression* arg)
|
||||
-> const Expression*;
|
||||
static auto MakeBinOp(int line_num, enum Operator op, const Expression* arg1,
|
||||
const Expression* arg2) -> const Expression*;
|
||||
static auto MakeCall(int line_num, const Expression* fun,
|
||||
const Expression* arg) -> const Expression*;
|
||||
static auto MakeGetField(int line_num, const Expression* exp,
|
||||
std::string field) -> const Expression*;
|
||||
static auto MakeTuple(int line_num, std::vector<FieldInitializer> args)
|
||||
-> const Expression*;
|
||||
static auto MakeIndex(int line_num, Expression exp, Expression i)
|
||||
-> const Expression*;
|
||||
static auto MakeIndex(int line_num, const Expression* exp,
|
||||
const Expression* i) -> const Expression*;
|
||||
static auto MakeTypeType(int line_num) -> const Expression*;
|
||||
static auto MakeIntType(int line_num) -> const Expression*;
|
||||
static auto MakeBoolType(int line_num) -> const Expression*;
|
||||
static auto MakeFunType(int line_num, Expression param, Expression ret)
|
||||
-> const Expression*;
|
||||
static auto MakeFunType(int line_num, const Expression* param,
|
||||
const Expression* ret) -> const Expression*;
|
||||
static auto MakeAutoType(int line_num) -> const Expression*;
|
||||
static auto MakeContinuationType(int line_num) -> const Expression*;
|
||||
|
||||
|
||||
@@ -8,23 +8,23 @@
|
||||
|
||||
namespace Carbon {
|
||||
|
||||
auto MakeFunDef(int line_num, std::string name, Expression ret_type,
|
||||
Expression param_pattern, const Statement* body)
|
||||
auto MakeFunDef(int line_num, std::string name, const Expression* ret_type,
|
||||
const Expression* param_pattern, const Statement* body)
|
||||
-> FunctionDefinition {
|
||||
FunctionDefinition f;
|
||||
f.line_num = line_num;
|
||||
f.name = std::move(name);
|
||||
f.return_type = std::move(ret_type);
|
||||
f.param_pattern = std::move(param_pattern);
|
||||
f.return_type = ret_type;
|
||||
f.param_pattern = param_pattern;
|
||||
f.body = body;
|
||||
return f;
|
||||
}
|
||||
|
||||
void PrintFunDefDepth(const FunctionDefinition& f, int depth) {
|
||||
std::cout << "fn " << f.name << " ";
|
||||
PrintExp(&f.param_pattern);
|
||||
PrintExp(f.param_pattern);
|
||||
std::cout << " -> ";
|
||||
PrintExp(&f.return_type);
|
||||
PrintExp(f.return_type);
|
||||
if (f.body) {
|
||||
std::cout << " {" << std::endl;
|
||||
PrintStatement(f.body, depth);
|
||||
|
||||
@@ -13,13 +13,14 @@ namespace Carbon {
|
||||
struct FunctionDefinition {
|
||||
int line_num;
|
||||
std::string name;
|
||||
Expression param_pattern;
|
||||
Expression return_type;
|
||||
const Expression* param_pattern;
|
||||
const Expression* return_type;
|
||||
const Statement* body;
|
||||
};
|
||||
|
||||
auto MakeFunDef(int line_num, std::string name, Expression ret_type,
|
||||
Expression param, const Statement* body) -> FunctionDefinition;
|
||||
auto MakeFunDef(int line_num, std::string name, const Expression* ret_type,
|
||||
const Expression* param, const Statement* body)
|
||||
-> FunctionDefinition;
|
||||
void PrintFunDef(const FunctionDefinition&);
|
||||
void PrintFunDefDepth(const FunctionDefinition&, int);
|
||||
|
||||
|
||||
@@ -65,52 +65,53 @@ Run Statement::GetRun() const {
|
||||
return u.run;
|
||||
}
|
||||
|
||||
auto Statement::MakeExpStmt(int line_num, Expression exp) -> const Statement* {
|
||||
auto Statement::MakeExpStmt(int line_num, const Expression* exp)
|
||||
-> const Statement* {
|
||||
auto* s = new Statement();
|
||||
s->line_num = line_num;
|
||||
s->tag = StatementKind::ExpressionStatement;
|
||||
s->u.exp = new Expression(std::move(exp));
|
||||
s->u.exp = exp;
|
||||
return s;
|
||||
}
|
||||
|
||||
auto Statement::MakeAssign(int line_num, Expression lhs, Expression rhs)
|
||||
-> const Statement* {
|
||||
auto Statement::MakeAssign(int line_num, const Expression* lhs,
|
||||
const Expression* rhs) -> const Statement* {
|
||||
auto* s = new Statement();
|
||||
s->line_num = line_num;
|
||||
s->tag = StatementKind::Assign;
|
||||
s->u.assign.lhs = new Expression(std::move(lhs));
|
||||
s->u.assign.rhs = new Expression(std::move(rhs));
|
||||
s->u.assign.lhs = lhs;
|
||||
s->u.assign.rhs = rhs;
|
||||
return s;
|
||||
}
|
||||
|
||||
auto Statement::MakeVarDef(int line_num, Expression pat, Expression init)
|
||||
-> const Statement* {
|
||||
auto Statement::MakeVarDef(int line_num, const Expression* pat,
|
||||
const Expression* init) -> const Statement* {
|
||||
auto* s = new Statement();
|
||||
s->line_num = line_num;
|
||||
s->tag = StatementKind::VariableDefinition;
|
||||
s->u.variable_definition.pat = new Expression(std::move(pat));
|
||||
s->u.variable_definition.init = new Expression(std::move(init));
|
||||
s->u.variable_definition.pat = pat;
|
||||
s->u.variable_definition.init = init;
|
||||
return s;
|
||||
}
|
||||
|
||||
auto Statement::MakeIf(int line_num, Expression cond,
|
||||
auto Statement::MakeIf(int line_num, const Expression* cond,
|
||||
const Statement* then_stmt, const Statement* else_stmt)
|
||||
-> const Statement* {
|
||||
auto* s = new Statement();
|
||||
s->line_num = line_num;
|
||||
s->tag = StatementKind::If;
|
||||
s->u.if_stmt.cond = new Expression(std::move(cond));
|
||||
s->u.if_stmt.cond = cond;
|
||||
s->u.if_stmt.then_stmt = then_stmt;
|
||||
s->u.if_stmt.else_stmt = else_stmt;
|
||||
return s;
|
||||
}
|
||||
|
||||
auto Statement::MakeWhile(int line_num, Expression cond, const Statement* body)
|
||||
-> const Statement* {
|
||||
auto Statement::MakeWhile(int line_num, const Expression* cond,
|
||||
const Statement* body) -> const Statement* {
|
||||
auto* s = new Statement();
|
||||
s->line_num = line_num;
|
||||
s->tag = StatementKind::While;
|
||||
s->u.while_stmt.cond = new Expression(std::move(cond));
|
||||
s->u.while_stmt.cond = cond;
|
||||
s->u.while_stmt.body = body;
|
||||
return s;
|
||||
}
|
||||
@@ -129,11 +130,12 @@ auto Statement::MakeContinue(int line_num) -> const Statement* {
|
||||
return s;
|
||||
}
|
||||
|
||||
auto Statement::MakeReturn(int line_num, Expression e) -> const Statement* {
|
||||
auto Statement::MakeReturn(int line_num, const Expression* e)
|
||||
-> const Statement* {
|
||||
auto* s = new Statement();
|
||||
s->line_num = line_num;
|
||||
s->tag = StatementKind::Return;
|
||||
s->u.return_stmt = new Expression(std::move(e));
|
||||
s->u.return_stmt = e;
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -157,13 +159,13 @@ auto Statement::MakeBlock(int line_num, const Statement* stmt)
|
||||
}
|
||||
|
||||
auto Statement::MakeMatch(
|
||||
int line_num, Expression exp,
|
||||
int line_num, const Expression* exp,
|
||||
std::list<std::pair<const Expression*, const Statement*>>* clauses)
|
||||
-> const Statement* {
|
||||
auto* s = new Statement();
|
||||
s->line_num = line_num;
|
||||
s->tag = StatementKind::Match;
|
||||
s->u.match_stmt.exp = new Expression(std::move(exp));
|
||||
s->u.match_stmt.exp = exp;
|
||||
s->u.match_stmt.clauses = clauses;
|
||||
return s;
|
||||
}
|
||||
@@ -183,11 +185,12 @@ auto Statement::MakeContinuation(int line_num,
|
||||
}
|
||||
|
||||
// Returns an AST node for a run statement give its line number and argument.
|
||||
auto Statement::MakeRun(int line_num, Expression argument) -> const Statement* {
|
||||
auto Statement::MakeRun(int line_num, const Expression* argument)
|
||||
-> const Statement* {
|
||||
auto* run = new Statement();
|
||||
run->line_num = line_num;
|
||||
run->tag = StatementKind::Run;
|
||||
run->u.run.argument = new Expression(std::move(argument));
|
||||
run->u.run.argument = argument;
|
||||
return run;
|
||||
}
|
||||
|
||||
|
||||
@@ -80,23 +80,25 @@ struct Statement {
|
||||
StatementKind tag;
|
||||
|
||||
// Constructors
|
||||
static auto MakeExpStmt(int line_num, Expression exp) -> const Statement*;
|
||||
static auto MakeAssign(int line_num, Expression lhs, Expression rhs)
|
||||
static auto MakeExpStmt(int line_num, const Expression* exp)
|
||||
-> const Statement*;
|
||||
static auto MakeVarDef(int line_num, Expression pat, Expression init)
|
||||
static auto MakeAssign(int line_num, const Expression* lhs,
|
||||
const Expression* rhs) -> const Statement*;
|
||||
static auto MakeVarDef(int line_num, const Expression* pat,
|
||||
const Expression* init) -> const Statement*;
|
||||
static auto MakeIf(int line_num, const Expression* cond,
|
||||
const Statement* then_stmt, const Statement* else_stmt)
|
||||
-> const Statement*;
|
||||
static auto MakeIf(int line_num, Expression cond, const Statement* then_stmt,
|
||||
const Statement* else_stmt) -> const Statement*;
|
||||
static auto MakeReturn(int line_num, Expression e) -> const Statement*;
|
||||
static auto MakeReturn(int line_num, const Expression* e) -> const Statement*;
|
||||
static auto MakeSeq(int line_num, const Statement* s1, const Statement* s2)
|
||||
-> const Statement*;
|
||||
static auto MakeBlock(int line_num, const Statement* s) -> const Statement*;
|
||||
static auto MakeWhile(int line_num, Expression cond, const Statement* body)
|
||||
-> const Statement*;
|
||||
static auto MakeWhile(int line_num, const Expression* cond,
|
||||
const Statement* body) -> const Statement*;
|
||||
static auto MakeBreak(int line_num) -> const Statement*;
|
||||
static auto MakeContinue(int line_num) -> const Statement*;
|
||||
static auto MakeMatch(
|
||||
int line_num, Expression exp,
|
||||
int line_num, const Expression* exp,
|
||||
std::list<std::pair<const Expression*, const Statement*>>* clauses)
|
||||
-> const Statement*;
|
||||
// Returns an AST node for a continuation statement give its line number and
|
||||
@@ -110,7 +112,8 @@ struct Statement {
|
||||
// Returns an AST node for a run statement give its line number and argument.
|
||||
//
|
||||
// __run <argument>;
|
||||
static auto MakeRun(int line_num, Expression argument) -> const Statement*;
|
||||
static auto MakeRun(int line_num, const Expression* argument)
|
||||
-> const Statement*;
|
||||
// Returns an AST node for an await statement give its line number.
|
||||
//
|
||||
// __await;
|
||||
|
||||
@@ -315,7 +315,7 @@ void InitGlobals(std::list<Declaration>* fs) {
|
||||
auto ChoiceDeclaration::InitGlobals(Env& globals) const -> void {
|
||||
auto alts = new VarValues();
|
||||
for (const auto& [name, signature] : alternatives) {
|
||||
auto t = InterpExp(Env(), &signature);
|
||||
auto t = InterpExp(Env(), signature);
|
||||
alts->push_back(make_pair(name, t));
|
||||
}
|
||||
auto ct = Value::MakeChoiceTypeVal(name, alts);
|
||||
@@ -342,7 +342,7 @@ auto StructDeclaration::InitGlobals(Env& globals) const -> void {
|
||||
}
|
||||
|
||||
auto FunctionDeclaration::InitGlobals(Env& globals) const -> void {
|
||||
auto pt = InterpExp(globals, &definition.param_pattern);
|
||||
auto pt = InterpExp(globals, definition.param_pattern);
|
||||
auto f = Value::MakeFunVal(definition.name, pt, definition.body);
|
||||
Address a = state->heap.AllocateValue(f);
|
||||
globals.Set(definition.name, a);
|
||||
@@ -640,8 +640,7 @@ void StepLvalue() {
|
||||
if (act->pos == 0) {
|
||||
// { {e.f :: C, E, F} :: S, H}
|
||||
// -> { e :: [].f :: C, E, F} :: S, H}
|
||||
frame->todo.Push(
|
||||
MakeLvalAct(exp->GetFieldAccess().aggregate.GetPointer()));
|
||||
frame->todo.Push(MakeLvalAct(exp->GetFieldAccess().aggregate));
|
||||
act->pos++;
|
||||
} else {
|
||||
// { v :: [].f :: C, E, F} :: S, H}
|
||||
@@ -658,10 +657,10 @@ void StepLvalue() {
|
||||
if (act->pos == 0) {
|
||||
// { {e[i] :: C, E, F} :: S, H}
|
||||
// -> { e :: [][i] :: C, E, F} :: S, H}
|
||||
frame->todo.Push(MakeExpAct(exp->GetIndex().aggregate.GetPointer()));
|
||||
frame->todo.Push(MakeExpAct(exp->GetIndex().aggregate));
|
||||
act->pos++;
|
||||
} else if (act->pos == 1) {
|
||||
frame->todo.Push(MakeExpAct(exp->GetIndex().offset.GetPointer()));
|
||||
frame->todo.Push(MakeExpAct(exp->GetIndex().offset));
|
||||
act->pos++;
|
||||
} else if (act->pos == 2) {
|
||||
// { v :: [][i] :: C, E, F} :: S, H}
|
||||
@@ -684,8 +683,7 @@ void StepLvalue() {
|
||||
if (act->pos == 0) {
|
||||
// { {(f1=e1,...) :: C, E, F} :: S, H}
|
||||
// -> { {e1 :: (f1=[],...) :: C, E, F} :: S, H}
|
||||
const Expression* e1 =
|
||||
exp->GetTuple().fields[0].expression.GetPointer();
|
||||
const Expression* e1 = exp->GetTuple().fields[0].expression;
|
||||
frame->todo.Push(MakeLvalAct(e1));
|
||||
act->pos++;
|
||||
} else if (act->pos != static_cast<int>(exp->GetTuple().fields.size())) {
|
||||
@@ -693,8 +691,7 @@ void StepLvalue() {
|
||||
// H}
|
||||
// -> { { ek+1 :: (f1=v1,..., fk=vk, fk+1=[],...) :: C, E, F} :: S,
|
||||
// H}
|
||||
const Expression* elt =
|
||||
exp->GetTuple().fields[act->pos].expression.GetPointer();
|
||||
const Expression* elt = exp->GetTuple().fields[act->pos].expression;
|
||||
frame->todo.Push(MakeLvalAct(elt));
|
||||
act->pos++;
|
||||
} else {
|
||||
@@ -734,8 +731,7 @@ void StepExp() {
|
||||
switch (exp->tag()) {
|
||||
case ExpressionKind::PatternVariable: {
|
||||
if (act->pos == 0) {
|
||||
frame->todo.Push(
|
||||
MakeExpAct(exp->GetPatternVariable().type.GetPointer()));
|
||||
frame->todo.Push(MakeExpAct(exp->GetPatternVariable().type));
|
||||
act->pos++;
|
||||
} else {
|
||||
auto v = Value::MakeVarPatVal(exp->GetPatternVariable().name,
|
||||
@@ -749,10 +745,10 @@ void StepExp() {
|
||||
if (act->pos == 0) {
|
||||
// { { e[i] :: C, E, F} :: S, H}
|
||||
// -> { { e :: [][i] :: C, E, F} :: S, H}
|
||||
frame->todo.Push(MakeExpAct(exp->GetIndex().aggregate.GetPointer()));
|
||||
frame->todo.Push(MakeExpAct(exp->GetIndex().aggregate));
|
||||
act->pos++;
|
||||
} else if (act->pos == 1) {
|
||||
frame->todo.Push(MakeExpAct(exp->GetIndex().offset.GetPointer()));
|
||||
frame->todo.Push(MakeExpAct(exp->GetIndex().offset));
|
||||
act->pos++;
|
||||
} else if (act->pos == 2) {
|
||||
auto tuple = act->results[0];
|
||||
@@ -788,8 +784,7 @@ void StepExp() {
|
||||
if (exp->GetTuple().fields.size() > 0) {
|
||||
// { {(f1=e1,...) :: C, E, F} :: S, H}
|
||||
// -> { {e1 :: (f1=[],...) :: C, E, F} :: S, H}
|
||||
const Expression* e1 =
|
||||
exp->GetTuple().fields[0].expression.GetPointer();
|
||||
const Expression* e1 = exp->GetTuple().fields[0].expression;
|
||||
frame->todo.Push(MakeExpAct(e1));
|
||||
act->pos++;
|
||||
} else {
|
||||
@@ -800,8 +795,7 @@ void StepExp() {
|
||||
// H}
|
||||
// -> { { ek+1 :: (f1=v1,..., fk=vk, fk+1=[],...) :: C, E, F} :: S,
|
||||
// H}
|
||||
const Expression* elt =
|
||||
exp->GetTuple().fields[act->pos].expression.GetPointer();
|
||||
const Expression* elt = exp->GetTuple().fields[act->pos].expression;
|
||||
frame->todo.Push(MakeExpAct(elt));
|
||||
act->pos++;
|
||||
} else {
|
||||
@@ -813,8 +807,7 @@ void StepExp() {
|
||||
if (act->pos == 0) {
|
||||
// { { e.f :: C, E, F} :: S, H}
|
||||
// -> { { e :: [].f :: C, E, F} :: S, H}
|
||||
frame->todo.Push(
|
||||
MakeLvalAct(exp->GetFieldAccess().aggregate.GetPointer()));
|
||||
frame->todo.Push(MakeLvalAct(exp->GetFieldAccess().aggregate));
|
||||
act->pos++;
|
||||
} else {
|
||||
// { { v :: [].f :: C, E, F} :: S, H}
|
||||
@@ -859,8 +852,7 @@ void StepExp() {
|
||||
static_cast<int>(exp->GetPrimitiveOperator().arguments.size())) {
|
||||
// { {v :: op(vs,[],e,es) :: C, E, F} :: S, H}
|
||||
// -> { {e :: op(vs,v,[],es) :: C, E, F} :: S, H}
|
||||
const Expression* arg =
|
||||
&(exp->GetPrimitiveOperator().arguments[act->pos]);
|
||||
const Expression* arg = exp->GetPrimitiveOperator().arguments[act->pos];
|
||||
frame->todo.Push(MakeExpAct(arg));
|
||||
act->pos++;
|
||||
} else {
|
||||
@@ -876,12 +868,12 @@ void StepExp() {
|
||||
if (act->pos == 0) {
|
||||
// { {e1(e2) :: C, E, F} :: S, H}
|
||||
// -> { {e1 :: [](e2) :: C, E, F} :: S, H}
|
||||
frame->todo.Push(MakeExpAct(exp->GetCall().function.GetPointer()));
|
||||
frame->todo.Push(MakeExpAct(exp->GetCall().function));
|
||||
act->pos++;
|
||||
} else if (act->pos == 1) {
|
||||
// { { v :: [](e) :: C, E, F} :: S, H}
|
||||
// -> { { e :: v([]) :: C, E, F} :: S, H}
|
||||
frame->todo.Push(MakeExpAct(exp->GetCall().argument.GetPointer()));
|
||||
frame->todo.Push(MakeExpAct(exp->GetCall().argument));
|
||||
act->pos++;
|
||||
} else if (act->pos == 2) {
|
||||
// { { v2 :: v1([]) :: C, E, F} :: S, H}
|
||||
@@ -923,14 +915,12 @@ void StepExp() {
|
||||
}
|
||||
case ExpressionKind::FunctionT: {
|
||||
if (act->pos == 0) {
|
||||
frame->todo.Push(
|
||||
MakeExpAct(exp->GetFunctionType().parameter.GetPointer()));
|
||||
frame->todo.Push(MakeExpAct(exp->GetFunctionType().parameter));
|
||||
act->pos++;
|
||||
} else if (act->pos == 1) {
|
||||
// { { pt :: fn [] -> e :: C, E, F} :: S, H}
|
||||
// -> { { e :: fn pt -> []) :: C, E, F} :: S, H}
|
||||
frame->todo.Push(
|
||||
MakeExpAct(exp->GetFunctionType().return_type.GetPointer()));
|
||||
frame->todo.Push(MakeExpAct(exp->GetFunctionType().return_type));
|
||||
act->pos++;
|
||||
} else if (act->pos == 2) {
|
||||
// { { rt :: fn pt -> [] :: C, E, F} :: S, H}
|
||||
@@ -1233,7 +1223,7 @@ void StepStmt() {
|
||||
scopes.Push(scope);
|
||||
Stack<Action*> todo;
|
||||
todo.Push(MakeStmtAct(Statement::MakeReturn(
|
||||
stmt->line_num, *Expression::MakeTuple(stmt->line_num, {}))));
|
||||
stmt->line_num, Expression::MakeTuple(stmt->line_num, {}))));
|
||||
todo.Push(MakeStmtAct(stmt->GetContinuation().body));
|
||||
Frame* continuation_frame = new Frame("__continuation", scopes, todo);
|
||||
Address continuation_address = state->heap.AllocateValue(
|
||||
@@ -1257,7 +1247,7 @@ void StepStmt() {
|
||||
// Push an expression statement action to ignore the result
|
||||
// value from the continuation.
|
||||
Action* ignore_result = MakeStmtAct(Statement::MakeExpStmt(
|
||||
stmt->line_num, *Expression::MakeTuple(stmt->line_num, {})));
|
||||
stmt->line_num, Expression::MakeTuple(stmt->line_num, {})));
|
||||
ignore_result->pos = 0;
|
||||
frame->todo.Push(ignore_result);
|
||||
// Push the continuation onto the current stack.
|
||||
@@ -1402,7 +1392,7 @@ auto InterpProgram(std::list<Declaration>* fs) -> int {
|
||||
|
||||
const Expression* arg = Expression::MakeTuple(0, {});
|
||||
const Expression* call_main =
|
||||
Expression::MakeCall(0, *Expression::MakeVar(0, "main"), *arg);
|
||||
Expression::MakeCall(0, Expression::MakeVar(0, "main"), arg);
|
||||
auto todo = Stack(MakeExpAct(call_main));
|
||||
auto* scope = new Scope(globals, std::list<std::string>());
|
||||
auto* frame = new Frame("top", Stack(scope), todo);
|
||||
|
||||
@@ -67,15 +67,15 @@ auto ReifyType(const Value* t, int line_num) -> const Expression* {
|
||||
return Expression::MakeContinuationType(0);
|
||||
case ValKind::FunctionTV:
|
||||
return Expression::MakeFunType(
|
||||
0, *ReifyType(t->GetFunctionType().param, line_num),
|
||||
*ReifyType(t->GetFunctionType().ret, line_num));
|
||||
0, ReifyType(t->GetFunctionType().param, line_num),
|
||||
ReifyType(t->GetFunctionType().ret, line_num));
|
||||
case ValKind::TupleV: {
|
||||
std::vector<FieldInitializer> args;
|
||||
for (const TupleElement& field : *t->GetTuple().elements) {
|
||||
args.push_back(
|
||||
{.name = field.name,
|
||||
.expression = *ReifyType(state->heap.Read(field.address, line_num),
|
||||
line_num)});
|
||||
.expression = ReifyType(state->heap.Read(field.address, line_num),
|
||||
line_num)});
|
||||
}
|
||||
return Expression::MakeTuple(0, args);
|
||||
}
|
||||
@@ -85,7 +85,7 @@ auto ReifyType(const Value* t, int line_num) -> const Expression* {
|
||||
return Expression::MakeVar(0, *t->GetChoiceType().name);
|
||||
case ValKind::PointerTV:
|
||||
return Expression::MakeUnOp(
|
||||
0, Operator::Ptr, *ReifyType(t->GetPointerType().type, line_num));
|
||||
0, Operator::Ptr, ReifyType(t->GetPointerType().type, line_num));
|
||||
default:
|
||||
std::cerr << line_num << ": expected a type, not ";
|
||||
PrintValue(t, std::cerr);
|
||||
@@ -144,7 +144,7 @@ auto TypeCheckExp(const Expression* e, TypeEnv types, Env values,
|
||||
<< std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
auto t = InterpExp(values, e->GetPatternVariable().type.GetPointer());
|
||||
auto t = InterpExp(values, e->GetPatternVariable().type);
|
||||
if (t->tag == ValKind::AutoTV) {
|
||||
if (expected == nullptr) {
|
||||
std::cerr << e->line_num
|
||||
@@ -157,20 +157,18 @@ auto TypeCheckExp(const Expression* e, TypeEnv types, Env values,
|
||||
} else if (expected) {
|
||||
ExpectType(e->line_num, "pattern variable", t, expected);
|
||||
}
|
||||
auto new_e =
|
||||
Expression::MakeVarPat(e->line_num, e->GetPatternVariable().name,
|
||||
*ReifyType(t, e->line_num));
|
||||
auto new_e = Expression::MakeVarPat(
|
||||
e->line_num, e->GetPatternVariable().name, ReifyType(t, e->line_num));
|
||||
types.Set(e->GetPatternVariable().name, t);
|
||||
return TCResult(new_e, t, types);
|
||||
}
|
||||
case ExpressionKind::Index: {
|
||||
auto res = TypeCheckExp(e->GetIndex().aggregate.GetPointer(), types,
|
||||
values, nullptr, TCContext::ValueContext);
|
||||
auto res = TypeCheckExp(e->GetIndex().aggregate, types, values, nullptr,
|
||||
TCContext::ValueContext);
|
||||
auto t = res.type;
|
||||
switch (t->tag) {
|
||||
case ValKind::TupleV: {
|
||||
auto i =
|
||||
ToInteger(InterpExp(values, e->GetIndex().offset.GetPointer()));
|
||||
auto i = ToInteger(InterpExp(values, e->GetIndex().offset));
|
||||
std::string f = std::to_string(i);
|
||||
std::optional<Address> field_address = FindTupleField(f, t);
|
||||
if (field_address == std::nullopt) {
|
||||
@@ -182,7 +180,7 @@ auto TypeCheckExp(const Expression* e, TypeEnv types, Env values,
|
||||
}
|
||||
auto field_t = state->heap.Read(*field_address, e->line_num);
|
||||
auto new_e = Expression::MakeIndex(
|
||||
e->line_num, *res.exp, *Expression::MakeInt(e->line_num, i));
|
||||
e->line_num, res.exp, Expression::MakeInt(e->line_num, i));
|
||||
return TCResult(new_e, field_t, res.types);
|
||||
}
|
||||
default:
|
||||
@@ -222,10 +220,10 @@ auto TypeCheckExp(const Expression* e, TypeEnv types, Env values,
|
||||
arg_expected = state->heap.Read(
|
||||
(*expected->GetTuple().elements)[i].address, e->line_num);
|
||||
}
|
||||
auto arg_res = TypeCheckExp(arg->expression.GetPointer(), new_types,
|
||||
values, arg_expected, context);
|
||||
auto arg_res = TypeCheckExp(arg->expression, new_types, values,
|
||||
arg_expected, context);
|
||||
new_types = arg_res.types;
|
||||
new_args.push_back({.name = arg->name, .expression = *arg_res.exp});
|
||||
new_args.push_back({.name = arg->name, .expression = arg_res.exp});
|
||||
arg_types->push_back(
|
||||
{.name = arg->name,
|
||||
.address = state->heap.AllocateValue(arg_res.type)});
|
||||
@@ -235,8 +233,8 @@ auto TypeCheckExp(const Expression* e, TypeEnv types, Env values,
|
||||
return TCResult(tuple_e, tuple_t, new_types);
|
||||
}
|
||||
case ExpressionKind::GetField: {
|
||||
auto res = TypeCheckExp(e->GetFieldAccess().aggregate.GetPointer(), types,
|
||||
values, nullptr, TCContext::ValueContext);
|
||||
auto res = TypeCheckExp(e->GetFieldAccess().aggregate, types, values,
|
||||
nullptr, TCContext::ValueContext);
|
||||
auto t = res.type;
|
||||
switch (t->tag) {
|
||||
case ValKind::StructTV:
|
||||
@@ -316,14 +314,14 @@ auto TypeCheckExp(const Expression* e, TypeEnv types, Env values,
|
||||
case ExpressionKind::Boolean:
|
||||
return TCResult(e, Value::MakeBoolTypeVal(), types);
|
||||
case ExpressionKind::PrimitiveOp: {
|
||||
std::vector<Expression> es;
|
||||
std::vector<const Expression*> es;
|
||||
std::vector<const Value*> ts;
|
||||
auto new_types = types;
|
||||
for (const Expression& argument : e->GetPrimitiveOperator().arguments) {
|
||||
auto res = TypeCheckExp(&argument, types, values, nullptr,
|
||||
for (const Expression* argument : e->GetPrimitiveOperator().arguments) {
|
||||
auto res = TypeCheckExp(argument, types, values, nullptr,
|
||||
TCContext::ValueContext);
|
||||
new_types = res.types;
|
||||
es.push_back(*res.exp);
|
||||
es.push_back(res.exp);
|
||||
ts.push_back(res.type);
|
||||
}
|
||||
auto new_e =
|
||||
@@ -374,18 +372,18 @@ auto TypeCheckExp(const Expression* e, TypeEnv types, Env values,
|
||||
break;
|
||||
}
|
||||
case ExpressionKind::Call: {
|
||||
auto fun_res = TypeCheckExp(e->GetCall().function.GetPointer(), types,
|
||||
values, nullptr, TCContext::ValueContext);
|
||||
auto fun_res = TypeCheckExp(e->GetCall().function, types, values, nullptr,
|
||||
TCContext::ValueContext);
|
||||
switch (fun_res.type->tag) {
|
||||
case ValKind::FunctionTV: {
|
||||
auto fun_t = fun_res.type;
|
||||
auto arg_res =
|
||||
TypeCheckExp(e->GetCall().argument.GetPointer(), fun_res.types,
|
||||
values, fun_t->GetFunctionType().param, context);
|
||||
TypeCheckExp(e->GetCall().argument, fun_res.types, values,
|
||||
fun_t->GetFunctionType().param, context);
|
||||
ExpectType(e->line_num, "call", fun_t->GetFunctionType().param,
|
||||
arg_res.type);
|
||||
auto new_e =
|
||||
Expression::MakeCall(e->line_num, *fun_res.exp, *arg_res.exp);
|
||||
Expression::MakeCall(e->line_num, fun_res.exp, arg_res.exp);
|
||||
return TCResult(new_e, fun_t->GetFunctionType().ret, arg_res.types);
|
||||
}
|
||||
default: {
|
||||
@@ -403,25 +401,22 @@ auto TypeCheckExp(const Expression* e, TypeEnv types, Env values,
|
||||
switch (context) {
|
||||
case TCContext::ValueContext:
|
||||
case TCContext::TypeContext: {
|
||||
auto pt =
|
||||
InterpExp(values, e->GetFunctionType().parameter.GetPointer());
|
||||
auto rt =
|
||||
InterpExp(values, e->GetFunctionType().return_type.GetPointer());
|
||||
auto pt = InterpExp(values, e->GetFunctionType().parameter);
|
||||
auto rt = InterpExp(values, e->GetFunctionType().return_type);
|
||||
auto new_e =
|
||||
Expression::MakeFunType(e->line_num, *ReifyType(pt, e->line_num),
|
||||
*ReifyType(rt, e->line_num));
|
||||
Expression::MakeFunType(e->line_num, ReifyType(pt, e->line_num),
|
||||
ReifyType(rt, e->line_num));
|
||||
return TCResult(new_e, Value::MakeTypeTypeVal(), types);
|
||||
}
|
||||
case TCContext::PatternContext: {
|
||||
auto param_res =
|
||||
TypeCheckExp(e->GetFunctionType().parameter.GetPointer(), types,
|
||||
values, nullptr, context);
|
||||
auto param_res = TypeCheckExp(e->GetFunctionType().parameter, types,
|
||||
values, nullptr, context);
|
||||
auto ret_res =
|
||||
TypeCheckExp(e->GetFunctionType().return_type.GetPointer(),
|
||||
param_res.types, values, nullptr, context);
|
||||
TypeCheckExp(e->GetFunctionType().return_type, param_res.types,
|
||||
values, nullptr, context);
|
||||
auto new_e = Expression::MakeFunType(
|
||||
e->line_num, *ReifyType(param_res.type, e->line_num),
|
||||
*ReifyType(ret_res.type, e->line_num));
|
||||
e->line_num, ReifyType(param_res.type, e->line_num),
|
||||
ReifyType(ret_res.type, e->line_num));
|
||||
return TCResult(new_e, Value::MakeTypeTypeVal(), ret_res.types);
|
||||
}
|
||||
}
|
||||
@@ -473,7 +468,7 @@ auto TypeCheckStmt(const Statement* s, TypeEnv types, Env values,
|
||||
res_type, clause.first, clause.second, types, values, ret_type));
|
||||
}
|
||||
const Statement* new_s =
|
||||
Statement::MakeMatch(s->line_num, *res.exp, new_clauses);
|
||||
Statement::MakeMatch(s->line_num, res.exp, new_clauses);
|
||||
return TCStatement(new_s, types);
|
||||
}
|
||||
case StatementKind::While: {
|
||||
@@ -484,7 +479,7 @@ auto TypeCheckStmt(const Statement* s, TypeEnv types, Env values,
|
||||
auto body_res =
|
||||
TypeCheckStmt(s->GetWhile().body, types, values, ret_type);
|
||||
auto new_s =
|
||||
Statement::MakeWhile(s->line_num, *cnd_res.exp, body_res.stmt);
|
||||
Statement::MakeWhile(s->line_num, cnd_res.exp, body_res.stmt);
|
||||
return TCStatement(new_s, types);
|
||||
}
|
||||
case StatementKind::Break:
|
||||
@@ -503,7 +498,7 @@ auto TypeCheckStmt(const Statement* s, TypeEnv types, Env values,
|
||||
auto lhs_res = TypeCheckExp(s->GetVariableDefinition().pat, types, values,
|
||||
rhs_ty, TCContext::PatternContext);
|
||||
const Statement* new_s = Statement::MakeVarDef(
|
||||
s->line_num, *s->GetVariableDefinition().pat, *res.exp);
|
||||
s->line_num, s->GetVariableDefinition().pat, res.exp);
|
||||
return TCStatement(new_s, lhs_res.types);
|
||||
}
|
||||
case StatementKind::Sequence: {
|
||||
@@ -525,14 +520,13 @@ auto TypeCheckStmt(const Statement* s, TypeEnv types, Env values,
|
||||
TCContext::ValueContext);
|
||||
auto lhs_t = lhs_res.type;
|
||||
ExpectType(s->line_num, "assign", lhs_t, rhs_t);
|
||||
auto new_s =
|
||||
Statement::MakeAssign(s->line_num, *lhs_res.exp, *rhs_res.exp);
|
||||
auto new_s = Statement::MakeAssign(s->line_num, lhs_res.exp, rhs_res.exp);
|
||||
return TCStatement(new_s, lhs_res.types);
|
||||
}
|
||||
case StatementKind::ExpressionStatement: {
|
||||
auto res = TypeCheckExp(s->GetExpression(), types, values, nullptr,
|
||||
TCContext::ValueContext);
|
||||
auto new_s = Statement::MakeExpStmt(s->line_num, *res.exp);
|
||||
auto new_s = Statement::MakeExpStmt(s->line_num, res.exp);
|
||||
return TCStatement(new_s, types);
|
||||
}
|
||||
case StatementKind::If: {
|
||||
@@ -544,7 +538,7 @@ auto TypeCheckStmt(const Statement* s, TypeEnv types, Env values,
|
||||
TypeCheckStmt(s->GetIf().then_stmt, types, values, ret_type);
|
||||
auto els_res =
|
||||
TypeCheckStmt(s->GetIf().else_stmt, types, values, ret_type);
|
||||
auto new_s = Statement::MakeIf(s->line_num, *cnd_res.exp, thn_res.stmt,
|
||||
auto new_s = Statement::MakeIf(s->line_num, cnd_res.exp, thn_res.stmt,
|
||||
els_res.stmt);
|
||||
return TCStatement(new_s, types);
|
||||
}
|
||||
@@ -559,7 +553,7 @@ auto TypeCheckStmt(const Statement* s, TypeEnv types, Env values,
|
||||
} else {
|
||||
ExpectType(s->line_num, "return", ret_type, res.type);
|
||||
}
|
||||
return TCStatement(Statement::MakeReturn(s->line_num, *res.exp), types);
|
||||
return TCStatement(Statement::MakeReturn(s->line_num, res.exp), types);
|
||||
}
|
||||
case StatementKind::Continuation: {
|
||||
TCStatement body_result =
|
||||
@@ -578,7 +572,7 @@ auto TypeCheckStmt(const Statement* s, TypeEnv types, Env values,
|
||||
ExpectType(s->line_num, "argument of `run`",
|
||||
Value::MakeContinuationTypeVal(), argument_result.type);
|
||||
const Statement* new_run =
|
||||
Statement::MakeRun(s->line_num, *argument_result.exp);
|
||||
Statement::MakeRun(s->line_num, argument_result.exp);
|
||||
return TCStatement(new_run, types);
|
||||
}
|
||||
case StatementKind::Await: {
|
||||
@@ -593,7 +587,7 @@ auto CheckOrEnsureReturn(const Statement* stmt, bool void_return, int line_num)
|
||||
if (!stmt) {
|
||||
if (void_return) {
|
||||
return Statement::MakeReturn(line_num,
|
||||
*Expression::MakeTuple(line_num, {}));
|
||||
Expression::MakeTuple(line_num, {}));
|
||||
} else {
|
||||
std::cerr
|
||||
<< "control-flow reaches end of non-void function without a return"
|
||||
@@ -610,7 +604,7 @@ auto CheckOrEnsureReturn(const Statement* stmt, bool void_return, int line_num)
|
||||
auto s = CheckOrEnsureReturn(i->second, void_return, stmt->line_num);
|
||||
new_clauses->push_back(std::make_pair(i->first, s));
|
||||
}
|
||||
return Statement::MakeMatch(stmt->line_num, *stmt->GetMatch().exp,
|
||||
return Statement::MakeMatch(stmt->line_num, stmt->GetMatch().exp,
|
||||
new_clauses);
|
||||
}
|
||||
case StatementKind::Block:
|
||||
@@ -619,7 +613,7 @@ auto CheckOrEnsureReturn(const Statement* stmt, bool void_return, int line_num)
|
||||
void_return, stmt->line_num));
|
||||
case StatementKind::If:
|
||||
return Statement::MakeIf(
|
||||
stmt->line_num, *stmt->GetIf().cond,
|
||||
stmt->line_num, stmt->GetIf().cond,
|
||||
CheckOrEnsureReturn(stmt->GetIf().then_stmt, void_return,
|
||||
stmt->line_num),
|
||||
CheckOrEnsureReturn(stmt->GetIf().else_stmt, void_return,
|
||||
@@ -650,7 +644,7 @@ auto CheckOrEnsureReturn(const Statement* stmt, bool void_return, int line_num)
|
||||
return Statement::MakeSeq(
|
||||
stmt->line_num, stmt,
|
||||
Statement::MakeReturn(stmt->line_num,
|
||||
*Expression::MakeTuple(stmt->line_num, {})));
|
||||
Expression::MakeTuple(stmt->line_num, {})));
|
||||
} else {
|
||||
std::cerr
|
||||
<< stmt->line_num
|
||||
@@ -664,9 +658,9 @@ auto CheckOrEnsureReturn(const Statement* stmt, bool void_return, int line_num)
|
||||
|
||||
auto TypeCheckFunDef(const FunctionDefinition* f, TypeEnv types, Env values)
|
||||
-> struct FunctionDefinition* {
|
||||
auto param_res = TypeCheckExp(&f->param_pattern, types, values, nullptr,
|
||||
auto param_res = TypeCheckExp(f->param_pattern, types, values, nullptr,
|
||||
TCContext::PatternContext);
|
||||
auto return_type = InterpExp(values, &f->return_type);
|
||||
auto return_type = InterpExp(values, f->return_type);
|
||||
if (f->name == "main") {
|
||||
ExpectType(f->line_num, "return type of `main`", Value::MakeIntTypeVal(),
|
||||
return_type);
|
||||
@@ -676,18 +670,18 @@ auto TypeCheckFunDef(const FunctionDefinition* f, TypeEnv types, Env values)
|
||||
bool void_return = TypeEqual(return_type, Value::MakeUnitTypeVal());
|
||||
auto body = CheckOrEnsureReturn(res.stmt, void_return, f->line_num);
|
||||
return new FunctionDefinition(MakeFunDef(f->line_num, f->name,
|
||||
*ReifyType(return_type, f->line_num),
|
||||
ReifyType(return_type, f->line_num),
|
||||
f->param_pattern, body));
|
||||
}
|
||||
|
||||
auto TypeOfFunDef(TypeEnv types, Env values, const FunctionDefinition* fun_def)
|
||||
-> const Value* {
|
||||
auto param_res = TypeCheckExp(&fun_def->param_pattern, types, values, nullptr,
|
||||
auto param_res = TypeCheckExp(fun_def->param_pattern, types, values, nullptr,
|
||||
TCContext::PatternContext);
|
||||
auto ret = InterpExp(values, &fun_def->return_type);
|
||||
auto ret = InterpExp(values, fun_def->return_type);
|
||||
if (ret->tag == ValKind::AutoTV) {
|
||||
auto f = TypeCheckFunDef(fun_def, types, values);
|
||||
ret = InterpExp(values, &f->return_type);
|
||||
ret = InterpExp(values, f->return_type);
|
||||
}
|
||||
return Value::MakeFunTypeVal(param_res.type, ret);
|
||||
}
|
||||
@@ -792,7 +786,7 @@ auto StructDeclaration::TopLevel(TypeCheckContext& tops) const -> void {
|
||||
auto ChoiceDeclaration::TopLevel(TypeCheckContext& tops) const -> void {
|
||||
auto alts = new VarValues();
|
||||
for (const auto& [name, signature] : alternatives) {
|
||||
auto t = InterpExp(tops.values, &signature);
|
||||
auto t = InterpExp(tops.values, signature);
|
||||
alts->push_back(std::make_pair(name, t));
|
||||
}
|
||||
auto ct = Value::MakeChoiceTypeVal(name, alts);
|
||||
|
||||
@@ -33,7 +33,7 @@ TEST(ParenContentsTest, UnaryNoCommaAsExpression) {
|
||||
// )
|
||||
// ```
|
||||
ParenContents contents(
|
||||
{{.expression = *Expression::MakeInt(/*line_num=*/2, 42)}},
|
||||
{{.expression = Expression::MakeInt(/*line_num=*/2, 42)}},
|
||||
ParenContents::HasTrailingComma::No);
|
||||
|
||||
const Expression* expression = contents.AsExpression(/*line_num=*/1);
|
||||
@@ -43,7 +43,7 @@ TEST(ParenContentsTest, UnaryNoCommaAsExpression) {
|
||||
|
||||
TEST(ParenContentsTest, UnaryNoCommaAsTuple) {
|
||||
ParenContents contents(
|
||||
{{.expression = *Expression::MakeInt(/*line_num=*/2, 42)}},
|
||||
{{.expression = Expression::MakeInt(/*line_num=*/2, 42)}},
|
||||
ParenContents::HasTrailingComma::No);
|
||||
|
||||
const Expression* tuple = contents.AsTuple(/*line_num=*/1);
|
||||
@@ -56,7 +56,7 @@ TEST(ParenContentsTest, UnaryNoCommaAsTuple) {
|
||||
|
||||
TEST(ParenContentsTest, UnaryWithCommaAsExpression) {
|
||||
ParenContents contents(
|
||||
{{.expression = *Expression::MakeInt(/*line_num=*/2, 42)}},
|
||||
{{.expression = Expression::MakeInt(/*line_num=*/2, 42)}},
|
||||
ParenContents::HasTrailingComma::Yes);
|
||||
|
||||
const Expression* expression = contents.AsExpression(/*line_num=*/1);
|
||||
@@ -69,7 +69,7 @@ TEST(ParenContentsTest, UnaryWithCommaAsExpression) {
|
||||
|
||||
TEST(ParenContentsTest, UnaryWithCommaAsTuple) {
|
||||
ParenContents contents(
|
||||
{{.expression = *Expression::MakeInt(/*line_num=*/2, 42)}},
|
||||
{{.expression = Expression::MakeInt(/*line_num=*/2, 42)}},
|
||||
ParenContents::HasTrailingComma::Yes);
|
||||
|
||||
const Expression* tuple = contents.AsTuple(/*line_num=*/1);
|
||||
@@ -82,8 +82,8 @@ TEST(ParenContentsTest, UnaryWithCommaAsTuple) {
|
||||
|
||||
TEST(ParenContentsTest, BinaryAsExpression) {
|
||||
ParenContents contents(
|
||||
{{.expression = *Expression::MakeInt(/*line_num=*/2, 42)},
|
||||
{.expression = *Expression::MakeInt(/*line_num=*/3, 42)}},
|
||||
{{.expression = Expression::MakeInt(/*line_num=*/2, 42)},
|
||||
{.expression = Expression::MakeInt(/*line_num=*/3, 42)}},
|
||||
ParenContents::HasTrailingComma::Yes);
|
||||
|
||||
const Expression* expression = contents.AsExpression(/*line_num=*/1);
|
||||
@@ -97,8 +97,8 @@ TEST(ParenContentsTest, BinaryAsExpression) {
|
||||
|
||||
TEST(ParenContentsTest, BinaryAsTuple) {
|
||||
ParenContents contents(
|
||||
{{.expression = *Expression::MakeInt(/*line_num=*/2, 42)},
|
||||
{.expression = *Expression::MakeInt(/*line_num=*/3, 42)}},
|
||||
{{.expression = Expression::MakeInt(/*line_num=*/2, 42)},
|
||||
{.expression = Expression::MakeInt(/*line_num=*/3, 42)}},
|
||||
ParenContents::HasTrailingComma::Yes);
|
||||
|
||||
const Expression* tuple = contents.AsTuple(/*line_num=*/1);
|
||||
|
||||
@@ -110,8 +110,8 @@ void yy::parser::error(
|
||||
%type <Carbon::FieldInitializer> field_initializer
|
||||
%type <Carbon::ParenContents> paren_contents
|
||||
%type <std::vector<Carbon::FieldInitializer>> paren_contents_without_trailing_comma
|
||||
%type <std::pair<std::string, Carbon::Expression>> alternative
|
||||
%type <std::list<std::pair<std::string, Carbon::Expression>>> alternative_list
|
||||
%type <std::pair<std::string, const Carbon::Expression*>> alternative
|
||||
%type <std::list<std::pair<std::string, const Carbon::Expression*>>> alternative_list
|
||||
%type <std::pair<const Carbon::Expression*, const Carbon::Statement*>*> clause
|
||||
%type <std::list<std::pair<const Carbon::Expression*, const Carbon::Statement*>>*> clause_list
|
||||
%token END_OF_FILE 0
|
||||
@@ -205,9 +205,9 @@ expression:
|
||||
| expression designator
|
||||
{ $$ = Carbon::Expression::MakeGetField(yylineno, $1, $2); }
|
||||
| expression "[" expression "]"
|
||||
{ $$ = Carbon::Expression::MakeIndex(yylineno, *$1, *$3); }
|
||||
{ $$ = Carbon::Expression::MakeIndex(yylineno, $1, $3); }
|
||||
| identifier ":" expression
|
||||
{ $$ = Carbon::Expression::MakeVarPat(yylineno, $1, *$3); }
|
||||
{ $$ = Carbon::Expression::MakeVarPat(yylineno, $1, $3); }
|
||||
| integer_literal
|
||||
{ $$ = Carbon::Expression::MakeInt(yylineno, $1); }
|
||||
| TRUE
|
||||
@@ -226,33 +226,33 @@ expression:
|
||||
{ $$ = Carbon::Expression::MakeContinuationType(yylineno); }
|
||||
| paren_expression { $$ = $1; }
|
||||
| expression EQUAL_EQUAL expression
|
||||
{ $$ = Carbon::Expression::MakeBinOp(yylineno, Carbon::Operator::Eq, *$1, *$3); }
|
||||
{ $$ = Carbon::Expression::MakeBinOp(yylineno, Carbon::Operator::Eq, $1, $3); }
|
||||
| expression "+" expression
|
||||
{ $$ = Carbon::Expression::MakeBinOp(yylineno, Carbon::Operator::Add, *$1, *$3); }
|
||||
{ $$ = Carbon::Expression::MakeBinOp(yylineno, Carbon::Operator::Add, $1, $3); }
|
||||
| expression "-" expression
|
||||
{ $$ = Carbon::Expression::MakeBinOp(yylineno, Carbon::Operator::Sub, *$1, *$3); }
|
||||
{ $$ = Carbon::Expression::MakeBinOp(yylineno, Carbon::Operator::Sub, $1, $3); }
|
||||
| expression BINARY_STAR expression
|
||||
{ $$ = Carbon::Expression::MakeBinOp(yylineno, Carbon::Operator::Mul, *$1, *$3); }
|
||||
{ $$ = Carbon::Expression::MakeBinOp(yylineno, Carbon::Operator::Mul, $1, $3); }
|
||||
| expression AND expression
|
||||
{ $$ = Carbon::Expression::MakeBinOp(yylineno, Carbon::Operator::And, *$1, *$3); }
|
||||
{ $$ = Carbon::Expression::MakeBinOp(yylineno, Carbon::Operator::And, $1, $3); }
|
||||
| expression OR expression
|
||||
{ $$ = Carbon::Expression::MakeBinOp(yylineno, Carbon::Operator::Or, *$1, *$3); }
|
||||
{ $$ = Carbon::Expression::MakeBinOp(yylineno, Carbon::Operator::Or, $1, $3); }
|
||||
| NOT expression
|
||||
{ $$ = Carbon::Expression::MakeUnOp(yylineno, Carbon::Operator::Not, *$2); }
|
||||
{ $$ = Carbon::Expression::MakeUnOp(yylineno, Carbon::Operator::Not, $2); }
|
||||
| "-" expression %prec UNARY_MINUS
|
||||
{ $$ = Carbon::Expression::MakeUnOp(yylineno, Carbon::Operator::Neg, *$2); }
|
||||
{ $$ = Carbon::Expression::MakeUnOp(yylineno, Carbon::Operator::Neg, $2); }
|
||||
| PREFIX_STAR expression
|
||||
{ $$ = Carbon::Expression::MakeUnOp(yylineno, Carbon::Operator::Deref, *$2); }
|
||||
{ $$ = Carbon::Expression::MakeUnOp(yylineno, Carbon::Operator::Deref, $2); }
|
||||
| UNARY_STAR expression %prec PREFIX_STAR
|
||||
{ $$ = Carbon::Expression::MakeUnOp(yylineno, Carbon::Operator::Deref, *$2); }
|
||||
{ $$ = Carbon::Expression::MakeUnOp(yylineno, Carbon::Operator::Deref, $2); }
|
||||
| expression tuple
|
||||
{ $$ = Carbon::Expression::MakeCall(yylineno, *$1, *$2); }
|
||||
{ $$ = Carbon::Expression::MakeCall(yylineno, $1, $2); }
|
||||
| expression POSTFIX_STAR
|
||||
{ $$ = Carbon::Expression::MakeUnOp(yylineno, Carbon::Operator::Ptr, *$1); }
|
||||
{ $$ = Carbon::Expression::MakeUnOp(yylineno, Carbon::Operator::Ptr, $1); }
|
||||
| expression UNARY_STAR
|
||||
{ $$ = Carbon::Expression::MakeUnOp(yylineno, Carbon::Operator::Ptr, *$1); }
|
||||
{ $$ = Carbon::Expression::MakeUnOp(yylineno, Carbon::Operator::Ptr, $1); }
|
||||
| FNTY tuple return_type
|
||||
{ $$ = Carbon::Expression::MakeFunType(yylineno, *$2, *$3); }
|
||||
{ $$ = Carbon::Expression::MakeFunType(yylineno, $2, $3); }
|
||||
;
|
||||
designator: "." identifier { $$ = $2; }
|
||||
;
|
||||
@@ -264,9 +264,9 @@ tuple: "(" paren_contents ")"
|
||||
;
|
||||
field_initializer:
|
||||
pattern
|
||||
{ $$ = Carbon::FieldInitializer({"", *$1}); }
|
||||
{ $$ = Carbon::FieldInitializer({"", $1}); }
|
||||
| designator "=" pattern
|
||||
{ $$ = Carbon::FieldInitializer({$1, *$3}); }
|
||||
{ $$ = Carbon::FieldInitializer({$1, $3}); }
|
||||
;
|
||||
paren_contents:
|
||||
// Empty
|
||||
@@ -297,7 +297,7 @@ clause:
|
||||
| DEFAULT DBLARROW statement
|
||||
{
|
||||
auto vp = Carbon::Expression::MakeVarPat(yylineno, "_",
|
||||
*Carbon::Expression::MakeAutoType(yylineno));
|
||||
Carbon::Expression::MakeAutoType(yylineno));
|
||||
$$ = new std::pair<const Carbon::Expression*, const Carbon::Statement*>(vp, $3);
|
||||
}
|
||||
;
|
||||
@@ -311,29 +311,29 @@ clause_list:
|
||||
;
|
||||
statement:
|
||||
expression "=" expression ";"
|
||||
{ $$ = Carbon::Statement::MakeAssign(yylineno, *$1, *$3); }
|
||||
{ $$ = Carbon::Statement::MakeAssign(yylineno, $1, $3); }
|
||||
| VAR pattern "=" expression ";"
|
||||
{ $$ = Carbon::Statement::MakeVarDef(yylineno, *$2, *$4); }
|
||||
{ $$ = Carbon::Statement::MakeVarDef(yylineno, $2, $4); }
|
||||
| expression ";"
|
||||
{ $$ = Carbon::Statement::MakeExpStmt(yylineno, *$1); }
|
||||
{ $$ = Carbon::Statement::MakeExpStmt(yylineno, $1); }
|
||||
| IF "(" expression ")" statement optional_else
|
||||
{ $$ = Carbon::Statement::MakeIf(yylineno, *$3, $5, $6); }
|
||||
{ $$ = Carbon::Statement::MakeIf(yylineno, $3, $5, $6); }
|
||||
| WHILE "(" expression ")" statement
|
||||
{ $$ = Carbon::Statement::MakeWhile(yylineno, *$3, $5); }
|
||||
{ $$ = Carbon::Statement::MakeWhile(yylineno, $3, $5); }
|
||||
| BREAK ";"
|
||||
{ $$ = Carbon::Statement::MakeBreak(yylineno); }
|
||||
| CONTINUE ";"
|
||||
{ $$ = Carbon::Statement::MakeContinue(yylineno); }
|
||||
| RETURN expression ";"
|
||||
{ $$ = Carbon::Statement::MakeReturn(yylineno, *$2); }
|
||||
{ $$ = Carbon::Statement::MakeReturn(yylineno, $2); }
|
||||
| "{" statement_list "}"
|
||||
{ $$ = Carbon::Statement::MakeBlock(yylineno, $2); }
|
||||
| MATCH "(" expression ")" "{" clause_list "}"
|
||||
{ $$ = Carbon::Statement::MakeMatch(yylineno, *$3, $6); }
|
||||
{ $$ = Carbon::Statement::MakeMatch(yylineno, $3, $6); }
|
||||
| CONTINUATION identifier statement
|
||||
{ $$ = Carbon::Statement::MakeContinuation(yylineno, $2, $3); }
|
||||
| RUN expression ";"
|
||||
{ $$ = Carbon::Statement::MakeRun(yylineno, *$2); }
|
||||
{ $$ = Carbon::Statement::MakeRun(yylineno, $2); }
|
||||
| AWAIT ";"
|
||||
{ $$ = Carbon::Statement::MakeAwait(yylineno); }
|
||||
;
|
||||
@@ -356,16 +356,16 @@ return_type:
|
||||
;
|
||||
function_definition:
|
||||
FN identifier tuple return_type "{" statement_list "}"
|
||||
{ $$ = MakeFunDef(yylineno, $2, *$4, *$3, $6); }
|
||||
{ $$ = MakeFunDef(yylineno, $2, $4, $3, $6); }
|
||||
| FN identifier tuple DBLARROW expression ";"
|
||||
{
|
||||
$$ = Carbon::MakeFunDef(yylineno, $2, *Carbon::Expression::MakeAutoType(yylineno), *$3,
|
||||
Carbon::Statement::MakeReturn(yylineno, *$5));
|
||||
$$ = Carbon::MakeFunDef(yylineno, $2, Carbon::Expression::MakeAutoType(yylineno), $3,
|
||||
Carbon::Statement::MakeReturn(yylineno, $5));
|
||||
}
|
||||
;
|
||||
function_declaration:
|
||||
FN identifier tuple return_type ";"
|
||||
{ $$ = MakeFunDef(yylineno, $2, *$4, *$3, 0); }
|
||||
{ $$ = MakeFunDef(yylineno, $2, $4, $3, 0); }
|
||||
;
|
||||
variable_declaration: identifier ":" expression
|
||||
{ $$ = MakeField(yylineno, $1, $3); }
|
||||
@@ -381,19 +381,19 @@ member_list:
|
||||
;
|
||||
alternative:
|
||||
identifier tuple
|
||||
{ $$ = std::pair<std::string, Carbon::Expression>($1, *$2); }
|
||||
{ $$ = std::pair<std::string, const Carbon::Expression*>($1, $2); }
|
||||
| identifier
|
||||
{
|
||||
$$ = std::pair<std::string, Carbon::Expression>(
|
||||
$1, *Carbon::Expression::MakeTuple(yylineno, {}));
|
||||
$$ = std::pair<std::string, const Carbon::Expression*>(
|
||||
$1, Carbon::Expression::MakeTuple(yylineno, {}));
|
||||
}
|
||||
;
|
||||
alternative_list:
|
||||
// Empty
|
||||
{ $$ = std::list<std::pair<std::string, Carbon::Expression>>(); }
|
||||
{ $$ = std::list<std::pair<std::string, const Carbon::Expression*>>(); }
|
||||
| alternative
|
||||
{
|
||||
$$ = std::list<std::pair<std::string, Carbon::Expression>>();
|
||||
$$ = std::list<std::pair<std::string, const Carbon::Expression*>>();
|
||||
$$.push_front($1);
|
||||
}
|
||||
| alternative "," alternative_list
|
||||
|
||||
Reference in New Issue
Block a user