mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
change all expression and statement pointers to be const (#449)
* change all expression and statement pointers to be const * const in paren tests
This commit is contained in:
@@ -127,10 +127,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(alternatives) {}
|
||||
|
||||
void Print() const;
|
||||
@@ -143,8 +144,8 @@ struct ChoiceDeclaration {
|
||||
// Global variable definition implements the Declaration concept.
|
||||
class VariableDeclaration {
|
||||
public:
|
||||
VariableDeclaration(int source_location, std::string name, Expression* type,
|
||||
Expression* initializer)
|
||||
VariableDeclaration(int source_location, std::string name,
|
||||
const Expression* type, const Expression* initializer)
|
||||
: source_location(source_location),
|
||||
name(name),
|
||||
type(type),
|
||||
@@ -159,8 +160,8 @@ class VariableDeclaration {
|
||||
private:
|
||||
int source_location;
|
||||
std::string name;
|
||||
Expression* type;
|
||||
Expression* initializer;
|
||||
const Expression* type;
|
||||
const Expression* initializer;
|
||||
};
|
||||
|
||||
} // namespace Carbon
|
||||
|
||||
@@ -8,28 +8,28 @@
|
||||
|
||||
namespace Carbon {
|
||||
|
||||
auto MakeTypeType(int line_num) -> Expression* {
|
||||
auto MakeTypeType(int line_num) -> const Expression* {
|
||||
auto* t = new Expression();
|
||||
t->tag = ExpressionKind::TypeT;
|
||||
t->line_num = line_num;
|
||||
return t;
|
||||
}
|
||||
|
||||
auto MakeIntType(int line_num) -> Expression* {
|
||||
auto MakeIntType(int line_num) -> const Expression* {
|
||||
auto* t = new Expression();
|
||||
t->tag = ExpressionKind::IntT;
|
||||
t->line_num = line_num;
|
||||
return t;
|
||||
}
|
||||
|
||||
auto MakeBoolType(int line_num) -> Expression* {
|
||||
auto MakeBoolType(int line_num) -> const Expression* {
|
||||
auto* t = new Expression();
|
||||
t->tag = ExpressionKind::BoolT;
|
||||
t->line_num = line_num;
|
||||
return t;
|
||||
}
|
||||
|
||||
auto MakeAutoType(int line_num) -> Expression* {
|
||||
auto MakeAutoType(int line_num) -> const Expression* {
|
||||
auto* t = new Expression();
|
||||
t->tag = ExpressionKind::AutoT;
|
||||
t->line_num = line_num;
|
||||
@@ -37,15 +37,15 @@ auto MakeAutoType(int line_num) -> Expression* {
|
||||
}
|
||||
|
||||
// Returns a Continuation type AST node at the given source location.
|
||||
auto MakeContinuationType(int line_num) -> Expression* {
|
||||
auto MakeContinuationType(int line_num) -> const Expression* {
|
||||
auto* type = new Expression();
|
||||
type->tag = ExpressionKind::ContinuationT;
|
||||
type->line_num = line_num;
|
||||
return type;
|
||||
}
|
||||
|
||||
auto MakeFunType(int line_num, Expression* param, Expression* ret)
|
||||
-> Expression* {
|
||||
auto MakeFunType(int line_num, const Expression* param, const Expression* ret)
|
||||
-> const Expression* {
|
||||
auto* t = new Expression();
|
||||
t->tag = ExpressionKind::FunctionT;
|
||||
t->line_num = line_num;
|
||||
@@ -54,7 +54,7 @@ auto MakeFunType(int line_num, Expression* param, Expression* ret)
|
||||
return t;
|
||||
}
|
||||
|
||||
auto MakeVar(int line_num, std::string var) -> Expression* {
|
||||
auto MakeVar(int line_num, std::string var) -> const Expression* {
|
||||
auto* v = new Expression();
|
||||
v->line_num = line_num;
|
||||
v->tag = ExpressionKind::Variable;
|
||||
@@ -62,8 +62,8 @@ auto MakeVar(int line_num, std::string var) -> Expression* {
|
||||
return v;
|
||||
}
|
||||
|
||||
auto MakeVarPat(int line_num, std::string var, Expression* type)
|
||||
-> Expression* {
|
||||
auto MakeVarPat(int line_num, std::string var, const Expression* type)
|
||||
-> const Expression* {
|
||||
auto* v = new Expression();
|
||||
v->line_num = line_num;
|
||||
v->tag = ExpressionKind::PatternVariable;
|
||||
@@ -72,7 +72,7 @@ auto MakeVarPat(int line_num, std::string var, Expression* type)
|
||||
return v;
|
||||
}
|
||||
|
||||
auto MakeInt(int line_num, int i) -> Expression* {
|
||||
auto MakeInt(int line_num, int i) -> const Expression* {
|
||||
auto* e = new Expression();
|
||||
e->line_num = line_num;
|
||||
e->tag = ExpressionKind::Integer;
|
||||
@@ -80,7 +80,7 @@ auto MakeInt(int line_num, int i) -> Expression* {
|
||||
return e;
|
||||
}
|
||||
|
||||
auto MakeBool(int line_num, bool b) -> Expression* {
|
||||
auto MakeBool(int line_num, bool b) -> const Expression* {
|
||||
auto* e = new Expression();
|
||||
e->line_num = line_num;
|
||||
e->tag = ExpressionKind::Boolean;
|
||||
@@ -88,8 +88,8 @@ auto MakeBool(int line_num, bool b) -> Expression* {
|
||||
return e;
|
||||
}
|
||||
|
||||
auto MakeOp(int line_num, enum Operator op, std::vector<Expression*>* args)
|
||||
-> Expression* {
|
||||
auto MakeOp(int line_num, enum Operator op,
|
||||
std::vector<const Expression*>* args) -> const Expression* {
|
||||
auto* e = new Expression();
|
||||
e->line_num = line_num;
|
||||
e->tag = ExpressionKind::PrimitiveOp;
|
||||
@@ -98,31 +98,33 @@ auto MakeOp(int line_num, enum Operator op, std::vector<Expression*>* args)
|
||||
return e;
|
||||
}
|
||||
|
||||
auto MakeUnOp(int line_num, enum Operator op, Expression* arg) -> Expression* {
|
||||
auto MakeUnOp(int line_num, enum Operator op, const Expression* arg)
|
||||
-> const Expression* {
|
||||
auto* e = new Expression();
|
||||
e->line_num = line_num;
|
||||
e->tag = ExpressionKind::PrimitiveOp;
|
||||
e->u.primitive_op.op = op;
|
||||
auto* args = new std::vector<Expression*>();
|
||||
auto* args = new std::vector<const Expression*>();
|
||||
args->push_back(arg);
|
||||
e->u.primitive_op.arguments = args;
|
||||
return e;
|
||||
}
|
||||
|
||||
auto MakeBinOp(int line_num, enum Operator op, Expression* arg1,
|
||||
Expression* arg2) -> Expression* {
|
||||
auto 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->tag = ExpressionKind::PrimitiveOp;
|
||||
e->u.primitive_op.op = op;
|
||||
auto* args = new std::vector<Expression*>();
|
||||
auto* args = new std::vector<const Expression*>();
|
||||
args->push_back(arg1);
|
||||
args->push_back(arg2);
|
||||
e->u.primitive_op.arguments = args;
|
||||
return e;
|
||||
}
|
||||
|
||||
auto MakeCall(int line_num, Expression* fun, Expression* arg) -> Expression* {
|
||||
auto MakeCall(int line_num, const Expression* fun, const Expression* arg)
|
||||
-> const Expression* {
|
||||
auto* e = new Expression();
|
||||
e->line_num = line_num;
|
||||
e->tag = ExpressionKind::Call;
|
||||
@@ -131,8 +133,8 @@ auto MakeCall(int line_num, Expression* fun, Expression* arg) -> Expression* {
|
||||
return e;
|
||||
}
|
||||
|
||||
auto MakeGetField(int line_num, Expression* exp, std::string field)
|
||||
-> Expression* {
|
||||
auto MakeGetField(int line_num, const Expression* exp, std::string field)
|
||||
-> const Expression* {
|
||||
auto* e = new Expression();
|
||||
e->line_num = line_num;
|
||||
e->tag = ExpressionKind::GetField;
|
||||
@@ -142,8 +144,8 @@ auto MakeGetField(int line_num, Expression* exp, std::string field)
|
||||
}
|
||||
|
||||
auto MakeTuple(int line_num,
|
||||
std::vector<std::pair<std::string, Expression*>>* args)
|
||||
-> Expression* {
|
||||
std::vector<std::pair<std::string, const Expression*>>* args)
|
||||
-> const Expression* {
|
||||
auto* e = new Expression();
|
||||
e->line_num = line_num;
|
||||
e->tag = ExpressionKind::Tuple;
|
||||
@@ -161,16 +163,17 @@ auto MakeTuple(int line_num,
|
||||
// Create an AST node for an empty tuple.
|
||||
// TODO(geoffromer): remove this and rewrite its callers to use
|
||||
// `MakeTuple(line_num, {})`, once that works.
|
||||
auto MakeUnit(int line_num) -> Expression* {
|
||||
auto MakeUnit(int line_num) -> const Expression* {
|
||||
auto* unit = new Expression();
|
||||
unit->line_num = line_num;
|
||||
unit->tag = ExpressionKind::Tuple;
|
||||
auto* args = new std::vector<std::pair<std::string, Expression*>>();
|
||||
auto* args = new std::vector<std::pair<std::string, const Expression*>>();
|
||||
unit->u.tuple.fields = args;
|
||||
return unit;
|
||||
}
|
||||
|
||||
auto MakeIndex(int line_num, Expression* exp, Expression* i) -> Expression* {
|
||||
auto MakeIndex(int line_num, const Expression* exp, const Expression* i)
|
||||
-> const Expression* {
|
||||
auto* e = new Expression();
|
||||
e->line_num = line_num;
|
||||
e->tag = ExpressionKind::Index;
|
||||
@@ -206,7 +209,7 @@ static void PrintOp(Operator op) {
|
||||
}
|
||||
|
||||
static void PrintFields(
|
||||
std::vector<std::pair<std::string, Expression*>>* fields) {
|
||||
std::vector<std::pair<std::string, const Expression*>>* fields) {
|
||||
int i = 0;
|
||||
for (auto iter = fields->begin(); iter != fields->end(); ++iter, ++i) {
|
||||
if (i != 0) {
|
||||
|
||||
@@ -47,73 +47,77 @@ struct Expression {
|
||||
} variable;
|
||||
|
||||
struct {
|
||||
Expression* aggregate;
|
||||
const Expression* aggregate;
|
||||
std::string* field;
|
||||
} get_field;
|
||||
|
||||
struct {
|
||||
Expression* aggregate;
|
||||
Expression* offset;
|
||||
const Expression* aggregate;
|
||||
const Expression* offset;
|
||||
} index;
|
||||
|
||||
struct {
|
||||
std::string* name;
|
||||
Expression* type;
|
||||
const Expression* type;
|
||||
} pattern_variable;
|
||||
|
||||
int integer;
|
||||
bool boolean;
|
||||
|
||||
struct {
|
||||
std::vector<std::pair<std::string, Expression*>>* fields;
|
||||
std::vector<std::pair<std::string, const Expression*>>* fields;
|
||||
} tuple;
|
||||
|
||||
struct {
|
||||
Operator op;
|
||||
std::vector<Expression*>* arguments;
|
||||
std::vector<const Expression*>* arguments;
|
||||
} primitive_op;
|
||||
|
||||
struct {
|
||||
Expression* function;
|
||||
Expression* argument;
|
||||
const Expression* function;
|
||||
const Expression* argument;
|
||||
} call;
|
||||
|
||||
struct {
|
||||
Expression* parameter;
|
||||
Expression* return_type;
|
||||
const Expression* parameter;
|
||||
const Expression* return_type;
|
||||
} function_type;
|
||||
|
||||
} u;
|
||||
};
|
||||
|
||||
auto MakeVar(int line_num, std::string var) -> Expression*;
|
||||
auto MakeVarPat(int line_num, std::string var, Expression* type) -> Expression*;
|
||||
auto MakeInt(int line_num, int i) -> Expression*;
|
||||
auto MakeBool(int line_num, bool b) -> Expression*;
|
||||
auto MakeOp(int line_num, Operator op, std::vector<Expression*>* args)
|
||||
-> Expression*;
|
||||
auto MakeUnOp(int line_num, enum Operator op, Expression* arg) -> Expression*;
|
||||
auto MakeBinOp(int line_num, enum Operator op, Expression* arg1,
|
||||
Expression* arg2) -> Expression*;
|
||||
auto MakeCall(int line_num, Expression* fun, Expression* arg) -> Expression*;
|
||||
auto MakeGetField(int line_num, Expression* exp, std::string field)
|
||||
-> Expression*;
|
||||
auto MakeVar(int line_num, std::string var) -> const Expression*;
|
||||
auto MakeVarPat(int line_num, std::string var, const Expression* type)
|
||||
-> const Expression*;
|
||||
auto MakeInt(int line_num, int i) -> const Expression*;
|
||||
auto MakeBool(int line_num, bool b) -> const Expression*;
|
||||
auto MakeOp(int line_num, Operator op, std::vector<const Expression*>* args)
|
||||
-> const Expression*;
|
||||
auto MakeUnOp(int line_num, enum Operator op, const Expression* arg)
|
||||
-> const Expression*;
|
||||
auto MakeBinOp(int line_num, enum Operator op, const Expression* arg1,
|
||||
const Expression* arg2) -> const Expression*;
|
||||
auto MakeCall(int line_num, const Expression* fun, const Expression* arg)
|
||||
-> const Expression*;
|
||||
auto MakeGetField(int line_num, const Expression* exp, std::string field)
|
||||
-> const Expression*;
|
||||
auto MakeTuple(int line_num,
|
||||
std::vector<std::pair<std::string, Expression*>>* args)
|
||||
-> Expression*;
|
||||
std::vector<std::pair<std::string, const Expression*>>* args)
|
||||
-> const Expression*;
|
||||
// Create an AST node for an empty tuple.
|
||||
auto MakeUnit(int line_num) -> Expression*;
|
||||
auto MakeIndex(int line_num, Expression* exp, Expression* i) -> Expression*;
|
||||
auto MakeUnit(int line_num) -> const Expression*;
|
||||
auto MakeIndex(int line_num, const Expression* exp, const Expression* i)
|
||||
-> const Expression*;
|
||||
|
||||
auto MakeTypeType(int line_num) -> Expression*;
|
||||
auto MakeIntType(int line_num) -> Expression*;
|
||||
auto MakeBoolType(int line_num) -> Expression*;
|
||||
auto MakeFunType(int line_num, Expression* param, Expression* ret)
|
||||
-> Expression*;
|
||||
auto MakeAutoType(int line_num) -> Expression*;
|
||||
auto MakeTypeType(int line_num) -> const Expression*;
|
||||
auto MakeIntType(int line_num) -> const Expression*;
|
||||
auto MakeBoolType(int line_num) -> const Expression*;
|
||||
auto MakeFunType(int line_num, const Expression* param, const Expression* ret)
|
||||
-> const Expression*;
|
||||
auto MakeAutoType(int line_num) -> const Expression*;
|
||||
// Returns a Continuation type AST node at the given source location,
|
||||
// which is the type of a continuation value.
|
||||
auto MakeContinuationType(int line_num) -> Expression*;
|
||||
auto MakeContinuationType(int line_num) -> const Expression*;
|
||||
|
||||
void PrintExp(const Expression* exp);
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
|
||||
namespace Carbon {
|
||||
|
||||
auto MakeFunDef(int line_num, std::string name, Expression* ret_type,
|
||||
Expression* param_pattern, Statement* body)
|
||||
auto MakeFunDef(int line_num, std::string name, const Expression* ret_type,
|
||||
const Expression* param_pattern, const Statement* body)
|
||||
-> struct FunctionDefinition* {
|
||||
auto* f = new struct FunctionDefinition();
|
||||
f->line_num = line_num;
|
||||
|
||||
@@ -13,13 +13,14 @@ namespace Carbon {
|
||||
struct FunctionDefinition {
|
||||
int line_num;
|
||||
std::string name;
|
||||
Expression* param_pattern;
|
||||
Expression* return_type;
|
||||
Statement* body;
|
||||
const Expression* param_pattern;
|
||||
const Expression* return_type;
|
||||
const Statement* body;
|
||||
};
|
||||
|
||||
auto MakeFunDef(int line_num, std::string name, Expression* ret_type,
|
||||
Expression* param, 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);
|
||||
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
|
||||
namespace Carbon {
|
||||
|
||||
auto MakeField(int line_num, std::string name, Expression* type) -> Member* {
|
||||
auto MakeField(int line_num, std::string name, const Expression* type)
|
||||
-> Member* {
|
||||
auto m = new Member();
|
||||
m->line_num = line_num;
|
||||
m->tag = MemberKind::FieldMember;
|
||||
|
||||
@@ -19,12 +19,13 @@ struct Member {
|
||||
union {
|
||||
struct {
|
||||
std::string* name;
|
||||
Expression* type;
|
||||
const Expression* type;
|
||||
} field;
|
||||
} u;
|
||||
};
|
||||
|
||||
auto MakeField(int line_num, std::string name, Expression* type) -> Member*;
|
||||
auto MakeField(int line_num, std::string name, const Expression* type)
|
||||
-> Member*;
|
||||
|
||||
void PrintMember(Member* m);
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
namespace Carbon {
|
||||
|
||||
auto MakeExpStmt(int line_num, Expression* exp) -> Statement* {
|
||||
auto MakeExpStmt(int line_num, const Expression* exp) -> const Statement* {
|
||||
auto* s = new Statement();
|
||||
s->line_num = line_num;
|
||||
s->tag = StatementKind::ExpressionStatement;
|
||||
@@ -16,7 +16,8 @@ auto MakeExpStmt(int line_num, Expression* exp) -> Statement* {
|
||||
return s;
|
||||
}
|
||||
|
||||
auto MakeAssign(int line_num, Expression* lhs, Expression* rhs) -> Statement* {
|
||||
auto 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;
|
||||
@@ -25,7 +26,8 @@ auto MakeAssign(int line_num, Expression* lhs, Expression* rhs) -> Statement* {
|
||||
return s;
|
||||
}
|
||||
|
||||
auto MakeVarDef(int line_num, Expression* pat, Expression* init) -> Statement* {
|
||||
auto 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;
|
||||
@@ -34,8 +36,8 @@ auto MakeVarDef(int line_num, Expression* pat, Expression* init) -> Statement* {
|
||||
return s;
|
||||
}
|
||||
|
||||
auto MakeIf(int line_num, Expression* cond, Statement* then_stmt,
|
||||
Statement* else_stmt) -> Statement* {
|
||||
auto 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;
|
||||
@@ -45,7 +47,8 @@ auto MakeIf(int line_num, Expression* cond, Statement* then_stmt,
|
||||
return s;
|
||||
}
|
||||
|
||||
auto MakeWhile(int line_num, Expression* cond, Statement* body) -> Statement* {
|
||||
auto 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;
|
||||
@@ -54,21 +57,21 @@ auto MakeWhile(int line_num, Expression* cond, Statement* body) -> Statement* {
|
||||
return s;
|
||||
}
|
||||
|
||||
auto MakeBreak(int line_num) -> Statement* {
|
||||
auto MakeBreak(int line_num) -> const Statement* {
|
||||
auto* s = new Statement();
|
||||
s->line_num = line_num;
|
||||
s->tag = StatementKind::Break;
|
||||
return s;
|
||||
}
|
||||
|
||||
auto MakeContinue(int line_num) -> Statement* {
|
||||
auto MakeContinue(int line_num) -> const Statement* {
|
||||
auto* s = new Statement();
|
||||
s->line_num = line_num;
|
||||
s->tag = StatementKind::Continue;
|
||||
return s;
|
||||
}
|
||||
|
||||
auto MakeReturn(int line_num, Expression* e) -> Statement* {
|
||||
auto MakeReturn(int line_num, const Expression* e) -> const Statement* {
|
||||
auto* s = new Statement();
|
||||
s->line_num = line_num;
|
||||
s->tag = StatementKind::Return;
|
||||
@@ -76,7 +79,8 @@ auto MakeReturn(int line_num, Expression* e) -> Statement* {
|
||||
return s;
|
||||
}
|
||||
|
||||
auto MakeSeq(int line_num, Statement* s1, Statement* s2) -> Statement* {
|
||||
auto MakeSeq(int line_num, const Statement* s1, const Statement* s2)
|
||||
-> const Statement* {
|
||||
auto* s = new Statement();
|
||||
s->line_num = line_num;
|
||||
s->tag = StatementKind::Sequence;
|
||||
@@ -85,7 +89,7 @@ auto MakeSeq(int line_num, Statement* s1, Statement* s2) -> Statement* {
|
||||
return s;
|
||||
}
|
||||
|
||||
auto MakeBlock(int line_num, Statement* stmt) -> Statement* {
|
||||
auto MakeBlock(int line_num, const Statement* stmt) -> const Statement* {
|
||||
auto* s = new Statement();
|
||||
s->line_num = line_num;
|
||||
s->tag = StatementKind::Block;
|
||||
@@ -93,9 +97,10 @@ auto MakeBlock(int line_num, Statement* stmt) -> Statement* {
|
||||
return s;
|
||||
}
|
||||
|
||||
auto MakeMatch(int line_num, Expression* exp,
|
||||
std::list<std::pair<Expression*, Statement*>>* clauses)
|
||||
-> Statement* {
|
||||
auto MakeMatch(
|
||||
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;
|
||||
@@ -107,7 +112,7 @@ auto MakeMatch(int line_num, Expression* exp,
|
||||
// Returns an AST node for a continuation statement give its line number and
|
||||
// parts.
|
||||
auto MakeContinuationStatement(int line_num, std::string continuation_variable,
|
||||
Statement* body) -> Statement* {
|
||||
const Statement* body) -> const Statement* {
|
||||
auto* continuation = new Statement();
|
||||
continuation->line_num = line_num;
|
||||
continuation->tag = StatementKind::Continuation;
|
||||
@@ -118,7 +123,7 @@ auto MakeContinuationStatement(int line_num, std::string continuation_variable,
|
||||
}
|
||||
|
||||
// Returns an AST node for a run statement give its line number and argument.
|
||||
auto MakeRun(int line_num, Expression* argument) -> Statement* {
|
||||
auto MakeRun(int line_num, const Expression* argument) -> const Statement* {
|
||||
auto* run = new Statement();
|
||||
run->line_num = line_num;
|
||||
run->tag = StatementKind::Run;
|
||||
@@ -127,14 +132,14 @@ auto MakeRun(int line_num, Expression* argument) -> Statement* {
|
||||
}
|
||||
|
||||
// Returns an AST node for an await statement give its line number.
|
||||
auto MakeAwait(int line_num) -> Statement* {
|
||||
auto MakeAwait(int line_num) -> const Statement* {
|
||||
auto* await = new Statement();
|
||||
await->line_num = line_num;
|
||||
await->tag = StatementKind::Await;
|
||||
return await;
|
||||
}
|
||||
|
||||
void PrintStatement(Statement* s, int depth) {
|
||||
void PrintStatement(const Statement* s, int depth) {
|
||||
if (!s) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -33,71 +33,76 @@ struct Statement {
|
||||
StatementKind tag;
|
||||
|
||||
union {
|
||||
Expression* exp;
|
||||
const Expression* exp;
|
||||
|
||||
struct {
|
||||
Expression* lhs;
|
||||
Expression* rhs;
|
||||
const Expression* lhs;
|
||||
const Expression* rhs;
|
||||
} assign;
|
||||
|
||||
struct {
|
||||
Expression* pat;
|
||||
Expression* init;
|
||||
const Expression* pat;
|
||||
const Expression* init;
|
||||
} variable_definition;
|
||||
|
||||
struct {
|
||||
Expression* cond;
|
||||
Statement* then_stmt;
|
||||
Statement* else_stmt;
|
||||
const Expression* cond;
|
||||
const Statement* then_stmt;
|
||||
const Statement* else_stmt;
|
||||
} if_stmt;
|
||||
|
||||
Expression* return_stmt;
|
||||
const Expression* return_stmt;
|
||||
|
||||
struct {
|
||||
Statement* stmt;
|
||||
Statement* next;
|
||||
const Statement* stmt;
|
||||
const Statement* next;
|
||||
} sequence;
|
||||
|
||||
struct {
|
||||
Statement* stmt;
|
||||
const Statement* stmt;
|
||||
} block;
|
||||
|
||||
struct {
|
||||
Expression* cond;
|
||||
Statement* body;
|
||||
const Expression* cond;
|
||||
const Statement* body;
|
||||
} while_stmt;
|
||||
|
||||
struct {
|
||||
Expression* exp;
|
||||
std::list<std::pair<Expression*, Statement*>>* clauses;
|
||||
const Expression* exp;
|
||||
std::list<std::pair<const Expression*, const Statement*>>* clauses;
|
||||
} match_stmt;
|
||||
|
||||
struct {
|
||||
std::string* continuation_variable;
|
||||
Statement* body;
|
||||
const Statement* body;
|
||||
} continuation;
|
||||
|
||||
struct {
|
||||
Expression* argument;
|
||||
const Expression* argument;
|
||||
} run;
|
||||
|
||||
} u;
|
||||
};
|
||||
|
||||
auto MakeExpStmt(int line_num, Expression* exp) -> Statement*;
|
||||
auto MakeAssign(int line_num, Expression* lhs, Expression* rhs) -> Statement*;
|
||||
auto MakeVarDef(int line_num, Expression* pat, Expression* init) -> Statement*;
|
||||
auto MakeIf(int line_num, Expression* cond, Statement* then_stmt,
|
||||
Statement* else_stmt) -> Statement*;
|
||||
auto MakeReturn(int line_num, Expression* e) -> Statement*;
|
||||
auto MakeSeq(int line_num, Statement* s1, Statement* s2) -> Statement*;
|
||||
auto MakeBlock(int line_num, Statement* s) -> Statement*;
|
||||
auto MakeWhile(int line_num, Expression* cond, Statement* body) -> Statement*;
|
||||
auto MakeBreak(int line_num) -> Statement*;
|
||||
auto MakeContinue(int line_num) -> Statement*;
|
||||
auto MakeMatch(int line_num, Expression* exp,
|
||||
std::list<std::pair<Expression*, Statement*>>* clauses)
|
||||
-> Statement*;
|
||||
auto MakeExpStmt(int line_num, const Expression* exp) -> const Statement*;
|
||||
auto MakeAssign(int line_num, const Expression* lhs, const Expression* rhs)
|
||||
-> const Statement*;
|
||||
auto MakeVarDef(int line_num, const Expression* pat, const Expression* init)
|
||||
-> const Statement*;
|
||||
auto MakeIf(int line_num, const Expression* cond, const Statement* then_stmt,
|
||||
const Statement* else_stmt) -> const Statement*;
|
||||
auto MakeReturn(int line_num, const Expression* e) -> const Statement*;
|
||||
auto MakeSeq(int line_num, const Statement* s1, const Statement* s2)
|
||||
-> const Statement*;
|
||||
auto MakeBlock(int line_num, const Statement* s) -> const Statement*;
|
||||
auto MakeWhile(int line_num, const Expression* cond, const Statement* body)
|
||||
-> const Statement*;
|
||||
auto MakeBreak(int line_num) -> const Statement*;
|
||||
auto MakeContinue(int line_num) -> const Statement*;
|
||||
auto MakeMatch(
|
||||
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
|
||||
// contituent parts.
|
||||
//
|
||||
@@ -105,17 +110,17 @@ auto MakeMatch(int line_num, Expression* exp,
|
||||
// <body>
|
||||
// }
|
||||
auto MakeContinuationStatement(int line_num, std::string continuation_variable,
|
||||
Statement* body) -> Statement*;
|
||||
const Statement* body) -> const Statement*;
|
||||
// Returns an AST node for a run statement give its line number and argument.
|
||||
//
|
||||
// __run <argument>;
|
||||
auto MakeRun(int line_num, Expression* argument) -> Statement*;
|
||||
auto MakeRun(int line_num, const Expression* argument) -> const Statement*;
|
||||
// Returns an AST node for an await statement give its line number.
|
||||
//
|
||||
// __await;
|
||||
auto MakeAwait(int line_num) -> Statement*;
|
||||
auto MakeAwait(int line_num) -> const Statement*;
|
||||
|
||||
void PrintStatement(Statement*, int);
|
||||
void PrintStatement(const Statement*, int);
|
||||
|
||||
} // namespace Carbon
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ void PrintActList(Stack<Action*> ls, std::ostream& out) {
|
||||
}
|
||||
}
|
||||
|
||||
auto MakeExpAct(Expression* e) -> Action* {
|
||||
auto MakeExpAct(const Expression* e) -> Action* {
|
||||
auto* act = new Action();
|
||||
act->tag = ActionKind::ExpressionAction;
|
||||
act->u.exp = e;
|
||||
@@ -67,7 +67,7 @@ auto MakeExpAct(Expression* e) -> Action* {
|
||||
return act;
|
||||
}
|
||||
|
||||
auto MakeLvalAct(Expression* e) -> Action* {
|
||||
auto MakeLvalAct(const Expression* e) -> Action* {
|
||||
auto* act = new Action();
|
||||
act->tag = ActionKind::LValAction;
|
||||
act->u.exp = e;
|
||||
@@ -75,7 +75,7 @@ auto MakeLvalAct(Expression* e) -> Action* {
|
||||
return act;
|
||||
}
|
||||
|
||||
auto MakeStmtAct(Statement* s) -> Action* {
|
||||
auto MakeStmtAct(const Statement* s) -> Action* {
|
||||
auto* act = new Action();
|
||||
act->tag = ActionKind::StatementAction;
|
||||
act->u.stmt = s;
|
||||
|
||||
@@ -27,8 +27,8 @@ enum class ActionKind {
|
||||
struct Action {
|
||||
ActionKind tag;
|
||||
union {
|
||||
Expression* exp; // for LValAction and ExpressionAction
|
||||
Statement* stmt;
|
||||
const Expression* exp; // for LValAction and ExpressionAction
|
||||
const Statement* stmt;
|
||||
const Value* val; // for finished actions with a value (ValAction)
|
||||
Address delete_tmp;
|
||||
} u;
|
||||
@@ -38,9 +38,9 @@ struct Action {
|
||||
|
||||
void PrintAct(Action* act, std::ostream& out);
|
||||
void PrintActList(Stack<Action*> ls, std::ostream& out);
|
||||
auto MakeExpAct(Expression* e) -> Action*;
|
||||
auto MakeLvalAct(Expression* e) -> Action*;
|
||||
auto MakeStmtAct(Statement* s) -> Action*;
|
||||
auto MakeExpAct(const Expression* e) -> Action*;
|
||||
auto MakeLvalAct(const Expression* e) -> Action*;
|
||||
auto MakeStmtAct(const Statement* s) -> Action*;
|
||||
auto MakeValAct(const Value* v) -> Action*;
|
||||
auto MakeExpToLvalAct() -> Action*;
|
||||
auto MakeDeleteAct(Address a) -> Action*;
|
||||
|
||||
@@ -387,7 +387,7 @@ void KillLocals(int line_num, Frame* frame) {
|
||||
}
|
||||
}
|
||||
|
||||
void CreateTuple(Frame* frame, Action* act, Expression* /*exp*/) {
|
||||
void CreateTuple(Frame* frame, Action* act, const Expression* /*exp*/) {
|
||||
// { { (v1,...,vn) :: C, E, F} :: S, H}
|
||||
// -> { { `(v1,...,vn) :: C, E, F} :: S, H}
|
||||
auto elts = new std::vector<std::pair<std::string, Address>>();
|
||||
@@ -566,7 +566,7 @@ void PatternAssignment(const Value* pat, const Value* val, int line_num) {
|
||||
void StepLvalue() {
|
||||
Frame* frame = state->stack.Top();
|
||||
Action* act = frame->todo.Top();
|
||||
Expression* exp = act->u.exp;
|
||||
const Expression* exp = act->u.exp;
|
||||
if (tracing_output) {
|
||||
std::cout << "--- step lvalue ";
|
||||
PrintExp(exp);
|
||||
@@ -606,7 +606,7 @@ void StepLvalue() {
|
||||
case ExpressionKind::Tuple: {
|
||||
// { {(f1=e1,...) :: C, E, F} :: S, H}
|
||||
// -> { {e1 :: (f1=[],...) :: C, E, F} :: S, H}
|
||||
Expression* e1 = (*exp->u.tuple.fields)[0].second;
|
||||
const Expression* e1 = (*exp->u.tuple.fields)[0].second;
|
||||
frame->todo.Push(MakeLvalAct(e1));
|
||||
act->pos++;
|
||||
break;
|
||||
@@ -634,7 +634,7 @@ void StepLvalue() {
|
||||
void StepExp() {
|
||||
Frame* frame = state->stack.Top();
|
||||
Action* act = frame->todo.Top();
|
||||
Expression* exp = act->u.exp;
|
||||
const Expression* exp = act->u.exp;
|
||||
if (tracing_output) {
|
||||
std::cout << "--- step exp ";
|
||||
PrintExp(exp);
|
||||
@@ -657,7 +657,7 @@ void StepExp() {
|
||||
if (exp->u.tuple.fields->size() > 0) {
|
||||
// { {(f1=e1,...) :: C, E, F} :: S, H}
|
||||
// -> { {e1 :: (f1=[],...) :: C, E, F} :: S, H}
|
||||
Expression* e1 = (*exp->u.tuple.fields)[0].second;
|
||||
const Expression* e1 = (*exp->u.tuple.fields)[0].second;
|
||||
frame->todo.Push(MakeExpAct(e1));
|
||||
act->pos++;
|
||||
} else {
|
||||
@@ -788,7 +788,7 @@ auto IsBlockAct(Action* act) -> bool {
|
||||
void StepStmt() {
|
||||
Frame* frame = state->stack.Top();
|
||||
Action* act = frame->todo.Top();
|
||||
Statement* const stmt = act->u.stmt;
|
||||
const Statement* stmt = act->u.stmt;
|
||||
assert(stmt != nullptr && "null statement!");
|
||||
if (tracing_output) {
|
||||
std::cout << "--- step stmt ";
|
||||
@@ -1027,7 +1027,7 @@ void HandleValue() {
|
||||
break;
|
||||
}
|
||||
case ActionKind::LValAction: {
|
||||
Expression* exp = act->u.exp;
|
||||
const Expression* exp = act->u.exp;
|
||||
switch (exp->tag) {
|
||||
case ExpressionKind::GetField: {
|
||||
// { v :: [].f :: C, E, F} :: S, H}
|
||||
@@ -1066,7 +1066,7 @@ void HandleValue() {
|
||||
// H}
|
||||
// -> { { ek+1 :: (f1=v1,..., fk=vk, fk+1=[],...) :: C, E, F} :: S,
|
||||
// H}
|
||||
Expression* elt = (*exp->u.tuple.fields)[act->pos].second;
|
||||
const Expression* elt = (*exp->u.tuple.fields)[act->pos].second;
|
||||
frame->todo.Pop(1);
|
||||
frame->todo.Push(MakeLvalAct(elt));
|
||||
} else {
|
||||
@@ -1083,7 +1083,7 @@ void HandleValue() {
|
||||
break;
|
||||
}
|
||||
case ActionKind::ExpressionAction: {
|
||||
Expression* exp = act->u.exp;
|
||||
const Expression* exp = act->u.exp;
|
||||
switch (exp->tag) {
|
||||
case ExpressionKind::PatternVariable: {
|
||||
auto v =
|
||||
@@ -1098,7 +1098,7 @@ void HandleValue() {
|
||||
// H}
|
||||
// -> { { ek+1 :: (f1=v1,..., fk=vk, fk+1=[],...) :: C, E, F} :: S,
|
||||
// H}
|
||||
Expression* elt = (*exp->u.tuple.fields)[act->pos].second;
|
||||
const Expression* elt = (*exp->u.tuple.fields)[act->pos].second;
|
||||
frame->todo.Pop(1);
|
||||
frame->todo.Push(MakeExpAct(elt));
|
||||
} else {
|
||||
@@ -1153,7 +1153,7 @@ void HandleValue() {
|
||||
static_cast<int>(exp->u.primitive_op.arguments->size())) {
|
||||
// { {v :: op(vs,[],e,es) :: C, E, F} :: S, H}
|
||||
// -> { {e :: op(vs,v,[],es) :: C, E, F} :: S, H}
|
||||
Expression* arg = (*exp->u.primitive_op.arguments)[act->pos];
|
||||
const Expression* arg = (*exp->u.primitive_op.arguments)[act->pos];
|
||||
frame->todo.Pop(1);
|
||||
frame->todo.Push(MakeExpAct(arg));
|
||||
} else {
|
||||
@@ -1214,7 +1214,7 @@ void HandleValue() {
|
||||
break;
|
||||
}
|
||||
case ActionKind::StatementAction: {
|
||||
Statement* stmt = act->u.stmt;
|
||||
const Statement* stmt = act->u.stmt;
|
||||
switch (stmt->tag) {
|
||||
case StatementKind::ExpressionStatement:
|
||||
frame->todo.Pop(2);
|
||||
@@ -1328,7 +1328,8 @@ void HandleValue() {
|
||||
if (matches) { // we have a match, start the body
|
||||
auto* new_scope = new Scope(*matches, vars);
|
||||
frame->scopes.Push(new_scope);
|
||||
Statement* body_block = MakeBlock(stmt->line_num, c->second);
|
||||
const Statement* body_block =
|
||||
MakeBlock(stmt->line_num, c->second);
|
||||
Action* body_act = MakeStmtAct(body_block);
|
||||
body_act->pos = 0;
|
||||
frame->todo.Pop(2);
|
||||
@@ -1440,9 +1441,9 @@ auto InterpProgram(std::list<Declaration>* fs) -> int {
|
||||
}
|
||||
InitGlobals(fs);
|
||||
|
||||
Expression* arg =
|
||||
MakeTuple(0, new std::vector<std::pair<std::string, Expression*>>());
|
||||
Expression* call_main = MakeCall(0, MakeVar(0, "main"), arg);
|
||||
const Expression* arg = MakeTuple(
|
||||
0, new std::vector<std::pair<std::string, const Expression*>>());
|
||||
const Expression* call_main = MakeCall(0, 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);
|
||||
@@ -1466,7 +1467,7 @@ auto InterpProgram(std::list<Declaration>* fs) -> int {
|
||||
}
|
||||
|
||||
// Interpret an expression at compile-time.
|
||||
auto InterpExp(Env values, Expression* e) -> const Value* {
|
||||
auto InterpExp(Env values, const Expression* e) -> const Value* {
|
||||
auto todo = Stack(MakeExpAct(e));
|
||||
auto* scope = new Scope(values, std::list<std::string>());
|
||||
auto* frame = new Frame("InterpExp", Stack(scope), todo);
|
||||
|
||||
@@ -77,7 +77,7 @@ auto ToInteger(const Value* v) -> int;
|
||||
/***** Interpreters *****/
|
||||
|
||||
auto InterpProgram(std::list<Declaration>* fs) -> int;
|
||||
auto InterpExp(Env values, Expression* e) -> const Value*;
|
||||
auto InterpExp(Env values, const Expression* e) -> const Value*;
|
||||
|
||||
} // namespace Carbon
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ void PrintTypeEnv(TypeEnv types, std::ostream& out) {
|
||||
}
|
||||
|
||||
// Reify type to type expression.
|
||||
auto ReifyType(const Value* t, int line_num) -> Expression* {
|
||||
auto ReifyType(const Value* t, int line_num) -> const Expression* {
|
||||
switch (t->tag) {
|
||||
case ValKind::VarTV:
|
||||
return MakeVar(0, *t->u.var_type);
|
||||
@@ -56,7 +56,7 @@ auto ReifyType(const Value* t, int line_num) -> Expression* {
|
||||
return MakeFunType(0, ReifyType(t->u.fun_type.param, line_num),
|
||||
ReifyType(t->u.fun_type.ret, line_num));
|
||||
case ValKind::TupleV: {
|
||||
auto args = new std::vector<std::pair<std::string, Expression*>>();
|
||||
auto args = new std::vector<std::pair<std::string, const Expression*>>();
|
||||
for (auto& field : *t->u.tuple.elts) {
|
||||
args->push_back(
|
||||
{field.first, ReifyType(state->heap[field.second], line_num)});
|
||||
@@ -93,7 +93,7 @@ auto ReifyType(const Value* t, int line_num) -> Expression* {
|
||||
// and it is used to implement `auto`, otherwise it is null.
|
||||
// context says what kind of position this expression is nested in,
|
||||
// whether it's a position that expects a value, a pattern, or a type.
|
||||
auto TypeCheckExp(Expression* e, TypeEnv types, Env values,
|
||||
auto TypeCheckExp(const Expression* e, TypeEnv types, Env values,
|
||||
const Value* expected, TCContext context) -> TCResult {
|
||||
switch (e->tag) {
|
||||
case ExpressionKind::PatternVariable: {
|
||||
@@ -148,7 +148,8 @@ auto TypeCheckExp(Expression* e, TypeEnv types, Env values,
|
||||
}
|
||||
}
|
||||
case ExpressionKind::Tuple: {
|
||||
auto new_args = new std::vector<std::pair<std::string, Expression*>>();
|
||||
auto new_args =
|
||||
new std::vector<std::pair<std::string, const Expression*>>();
|
||||
auto arg_types = new std::vector<std::pair<std::string, Address>>();
|
||||
auto new_types = types;
|
||||
int i = 0;
|
||||
@@ -184,7 +185,7 @@ auto TypeCheckExp(Expression* e, TypeEnv types, Env values,
|
||||
// Search for a field
|
||||
for (auto& field : *t->u.struct_type.fields) {
|
||||
if (*e->u.get_field.field == field.first) {
|
||||
Expression* new_e =
|
||||
const Expression* new_e =
|
||||
MakeGetField(e->line_num, res.exp, *e->u.get_field.field);
|
||||
return TCResult(new_e, field.second, res.types);
|
||||
}
|
||||
@@ -192,7 +193,7 @@ auto TypeCheckExp(Expression* e, TypeEnv types, Env values,
|
||||
// Search for a method
|
||||
for (auto& method : *t->u.struct_type.methods) {
|
||||
if (*e->u.get_field.field == method.first) {
|
||||
Expression* new_e =
|
||||
const Expression* new_e =
|
||||
MakeGetField(e->line_num, res.exp, *e->u.get_field.field);
|
||||
return TCResult(new_e, method.second, res.types);
|
||||
}
|
||||
@@ -217,7 +218,7 @@ auto TypeCheckExp(Expression* e, TypeEnv types, Env values,
|
||||
for (auto vt = t->u.choice_type.alternatives->begin();
|
||||
vt != t->u.choice_type.alternatives->end(); ++vt) {
|
||||
if (*e->u.get_field.field == vt->first) {
|
||||
Expression* new_e =
|
||||
const Expression* new_e =
|
||||
MakeGetField(e->line_num, res.exp, *e->u.get_field.field);
|
||||
auto fun_ty = MakeFunTypeVal(vt->second, t);
|
||||
return TCResult(new_e, fun_ty, res.types);
|
||||
@@ -252,7 +253,7 @@ auto TypeCheckExp(Expression* e, TypeEnv types, Env values,
|
||||
case ExpressionKind::Boolean:
|
||||
return TCResult(e, MakeBoolTypeVal(), types);
|
||||
case ExpressionKind::PrimitiveOp: {
|
||||
auto es = new std::vector<Expression*>();
|
||||
auto es = new std::vector<const Expression*>();
|
||||
std::vector<const Value*> ts;
|
||||
auto new_types = types;
|
||||
for (auto& argument : *e->u.primitive_op.arguments) {
|
||||
@@ -350,9 +351,10 @@ auto TypeCheckExp(Expression* e, TypeEnv types, Env values,
|
||||
}
|
||||
}
|
||||
|
||||
auto TypecheckCase(const Value* expected, Expression* pat, Statement* body,
|
||||
TypeEnv types, Env values, const Value*& ret_type)
|
||||
-> std::pair<Expression*, Statement*> {
|
||||
auto TypecheckCase(const Value* expected, const Expression* pat,
|
||||
const Statement* body, TypeEnv types, Env values,
|
||||
const Value*& ret_type)
|
||||
-> std::pair<const Expression*, const Statement*> {
|
||||
auto pat_res =
|
||||
TypeCheckExp(pat, types, values, expected, TCContext::PatternContext);
|
||||
auto res = TypeCheckStmt(body, pat_res.types, values, ret_type);
|
||||
@@ -366,7 +368,7 @@ auto TypecheckCase(const Value* expected, Expression* pat, Statement* body,
|
||||
// It is the declared return type of the enclosing function definition.
|
||||
// If the return type is "auto", then the return type is inferred from
|
||||
// the first return statement.
|
||||
auto TypeCheckStmt(Statement* s, TypeEnv types, Env values,
|
||||
auto TypeCheckStmt(const Statement* s, TypeEnv types, Env values,
|
||||
const Value*& ret_type) -> TCStatement {
|
||||
if (!s) {
|
||||
return TCStatement(s, types);
|
||||
@@ -376,12 +378,13 @@ auto TypeCheckStmt(Statement* s, TypeEnv types, Env values,
|
||||
auto res = TypeCheckExp(s->u.match_stmt.exp, types, values, nullptr,
|
||||
TCContext::ValueContext);
|
||||
auto res_type = res.type;
|
||||
auto new_clauses = new std::list<std::pair<Expression*, Statement*>>();
|
||||
auto new_clauses =
|
||||
new std::list<std::pair<const Expression*, const Statement*>>();
|
||||
for (auto& clause : *s->u.match_stmt.clauses) {
|
||||
new_clauses->push_back(TypecheckCase(
|
||||
res_type, clause.first, clause.second, types, values, ret_type));
|
||||
}
|
||||
Statement* new_s = MakeMatch(s->line_num, res.exp, new_clauses);
|
||||
const Statement* new_s = MakeMatch(s->line_num, res.exp, new_clauses);
|
||||
return TCStatement(new_s, types);
|
||||
}
|
||||
case StatementKind::While: {
|
||||
@@ -407,7 +410,7 @@ auto TypeCheckStmt(Statement* s, TypeEnv types, Env values,
|
||||
const Value* rhs_ty = res.type;
|
||||
auto lhs_res = TypeCheckExp(s->u.variable_definition.pat, types, values,
|
||||
rhs_ty, TCContext::PatternContext);
|
||||
Statement* new_s =
|
||||
const Statement* new_s =
|
||||
MakeVarDef(s->line_num, s->u.variable_definition.pat, res.exp);
|
||||
return TCStatement(new_s, lhs_res.types);
|
||||
}
|
||||
@@ -466,7 +469,7 @@ auto TypeCheckStmt(Statement* s, TypeEnv types, Env values,
|
||||
case StatementKind::Continuation: {
|
||||
TCStatement body_result =
|
||||
TypeCheckStmt(s->u.continuation.body, types, values, ret_type);
|
||||
Statement* new_continuation = MakeContinuationStatement(
|
||||
const Statement* new_continuation = MakeContinuationStatement(
|
||||
s->line_num, *s->u.continuation.continuation_variable,
|
||||
body_result.stmt);
|
||||
types.Set(*s->u.continuation.continuation_variable,
|
||||
@@ -478,7 +481,7 @@ auto TypeCheckStmt(Statement* s, TypeEnv types, Env values,
|
||||
nullptr, TCContext::ValueContext);
|
||||
ExpectType(s->line_num, "argument of `run`", MakeContinuationTypeVal(),
|
||||
argument_result.type);
|
||||
Statement* new_run = MakeRun(s->line_num, argument_result.exp);
|
||||
const Statement* new_run = MakeRun(s->line_num, argument_result.exp);
|
||||
return TCStatement(new_run, types);
|
||||
}
|
||||
case StatementKind::Await: {
|
||||
@@ -488,11 +491,11 @@ auto TypeCheckStmt(Statement* s, TypeEnv types, Env values,
|
||||
} // switch
|
||||
}
|
||||
|
||||
auto CheckOrEnsureReturn(Statement* stmt, bool void_return, int line_num)
|
||||
-> Statement* {
|
||||
auto CheckOrEnsureReturn(const Statement* stmt, bool void_return, int line_num)
|
||||
-> const Statement* {
|
||||
if (!stmt) {
|
||||
if (void_return) {
|
||||
auto args = new std::vector<std::pair<std::string, Expression*>>();
|
||||
auto args = new std::vector<std::pair<std::string, const Expression*>>();
|
||||
return MakeReturn(line_num, MakeTuple(line_num, args));
|
||||
} else {
|
||||
std::cerr
|
||||
@@ -503,7 +506,8 @@ auto CheckOrEnsureReturn(Statement* stmt, bool void_return, int line_num)
|
||||
}
|
||||
switch (stmt->tag) {
|
||||
case StatementKind::Match: {
|
||||
auto new_clauses = new std::list<std::pair<Expression*, Statement*>>();
|
||||
auto new_clauses =
|
||||
new std::list<std::pair<const Expression*, const Statement*>>();
|
||||
for (auto i = stmt->u.match_stmt.clauses->begin();
|
||||
i != stmt->u.match_stmt.clauses->end(); ++i) {
|
||||
auto s = CheckOrEnsureReturn(i->second, void_return, stmt->line_num);
|
||||
@@ -543,7 +547,8 @@ auto CheckOrEnsureReturn(Statement* stmt, bool void_return, int line_num)
|
||||
case StatementKind::Continue:
|
||||
case StatementKind::VariableDefinition:
|
||||
if (void_return) {
|
||||
auto args = new std::vector<std::pair<std::string, Expression*>>();
|
||||
auto args =
|
||||
new std::vector<std::pair<std::string, const Expression*>>();
|
||||
return MakeSeq(
|
||||
stmt->line_num, stmt,
|
||||
MakeReturn(stmt->line_num, MakeTuple(stmt->line_num, args)));
|
||||
|
||||
@@ -21,25 +21,26 @@ void PrintTypeEnv(TypeEnv types);
|
||||
enum class TCContext { ValueContext, PatternContext, TypeContext };
|
||||
|
||||
struct TCResult {
|
||||
TCResult(Expression* e, const Value* t, TypeEnv types)
|
||||
TCResult(const Expression* e, const Value* t, TypeEnv types)
|
||||
: exp(e), type(t), types(types) {}
|
||||
|
||||
Expression* exp;
|
||||
const Expression* exp;
|
||||
const Value* type;
|
||||
TypeEnv types;
|
||||
};
|
||||
|
||||
struct TCStatement {
|
||||
TCStatement(Statement* s, TypeEnv types) : stmt(s), types(types) {}
|
||||
TCStatement(const Statement* s, TypeEnv types) : stmt(s), types(types) {}
|
||||
|
||||
Statement* stmt;
|
||||
const Statement* stmt;
|
||||
TypeEnv types;
|
||||
};
|
||||
|
||||
auto TypeCheckExp(Expression* e, TypeEnv types, Env values,
|
||||
auto TypeCheckExp(const Expression* e, TypeEnv types, Env values,
|
||||
const Value* expected, TCContext context) -> TCResult;
|
||||
|
||||
auto TypeCheckStmt(Statement*, TypeEnv, Env, Value const*&) -> TCStatement;
|
||||
auto TypeCheckStmt(const Statement*, TypeEnv, Env, Value const*&)
|
||||
-> TCStatement;
|
||||
|
||||
auto TypeCheckFunDef(struct FunctionDefinition*, TypeEnv)
|
||||
-> struct FunctionDefinition*;
|
||||
|
||||
@@ -63,7 +63,7 @@ auto MakeBoolVal(bool b) -> const Value* {
|
||||
return v;
|
||||
}
|
||||
|
||||
auto MakeFunVal(std::string name, const Value* param, Statement* body)
|
||||
auto MakeFunVal(std::string name, const Value* param, const Statement* body)
|
||||
-> const Value* {
|
||||
auto* v = new Value();
|
||||
v->tag = ValKind::FunV;
|
||||
|
||||
@@ -61,7 +61,7 @@ struct Value {
|
||||
struct {
|
||||
std::string* name;
|
||||
const Value* param;
|
||||
Statement* body;
|
||||
const Statement* body;
|
||||
} fun;
|
||||
|
||||
struct {
|
||||
@@ -129,7 +129,7 @@ struct Value {
|
||||
auto MakeContinuation(std::vector<Frame*> stack) -> Value*;
|
||||
auto MakeIntVal(int i) -> const Value*;
|
||||
auto MakeBoolVal(bool b) -> const Value*;
|
||||
auto MakeFunVal(std::string name, const Value* param, Statement* body)
|
||||
auto MakeFunVal(std::string name, const Value* param, const Statement* body)
|
||||
-> const Value*;
|
||||
auto MakePtrVal(Address addr) -> const Value*;
|
||||
auto MakeStructVal(const Value* type, const Value* inits) -> const Value*;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
namespace Carbon {
|
||||
|
||||
Expression* ParenContents::AsExpression(int line_number) const {
|
||||
const Expression* ParenContents::AsExpression(int line_number) const {
|
||||
if (fields_.size() == 1 && fields_.front().name == "" &&
|
||||
has_trailing_comma_ == HasTrailingComma::No) {
|
||||
return fields_.front().expression;
|
||||
@@ -15,8 +15,9 @@ Expression* ParenContents::AsExpression(int line_number) const {
|
||||
}
|
||||
}
|
||||
|
||||
Expression* ParenContents::AsTuple(int line_number) const {
|
||||
auto vec = new std::vector<std::pair<std::string, Carbon::Expression*>>();
|
||||
const Expression* ParenContents::AsTuple(int line_number) const {
|
||||
auto vec =
|
||||
new std::vector<std::pair<std::string, const Carbon::Expression*>>();
|
||||
for (const FieldInitializer& initializer : fields_) {
|
||||
vec->push_back({initializer.name, initializer.expression});
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ struct FieldInitializer {
|
||||
std::string name;
|
||||
|
||||
// The expression that initializes the field.
|
||||
Expression* expression;
|
||||
const Expression* expression;
|
||||
};
|
||||
|
||||
// Represents the syntactic contents of an expression delimited by
|
||||
@@ -45,11 +45,11 @@ class ParenContents {
|
||||
ParenContents& operator=(const ParenContents&) = default;
|
||||
|
||||
// Returns the paren expression, interpreted as a tuple.
|
||||
Expression* AsTuple(int line_number) const;
|
||||
const Expression* AsTuple(int line_number) const;
|
||||
|
||||
// Returns the paren expression, with no external constraints on what kind
|
||||
// of expression it represents.
|
||||
Expression* AsExpression(int line_number) const;
|
||||
const Expression* AsExpression(int line_number) const;
|
||||
|
||||
private:
|
||||
std::vector<FieldInitializer> fields_;
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace {
|
||||
|
||||
TEST(ParenContentsTest, EmptyAsExpression) {
|
||||
ParenContents contents;
|
||||
Expression* expression = contents.AsExpression(/*line_num=*/1);
|
||||
const Expression* expression = contents.AsExpression(/*line_num=*/1);
|
||||
EXPECT_EQ(expression->line_num, 1);
|
||||
ASSERT_EQ(expression->tag, ExpressionKind::Tuple);
|
||||
EXPECT_EQ(expression->u.tuple.fields->size(), 0);
|
||||
@@ -19,7 +19,7 @@ TEST(ParenContentsTest, EmptyAsExpression) {
|
||||
|
||||
TEST(ParenContentsTest, EmptyAsTuple) {
|
||||
ParenContents contents;
|
||||
Expression* tuple = contents.AsTuple(/*line_num=*/1);
|
||||
const Expression* tuple = contents.AsTuple(/*line_num=*/1);
|
||||
EXPECT_EQ(tuple->line_num, 1);
|
||||
ASSERT_EQ(tuple->tag, ExpressionKind::Tuple);
|
||||
EXPECT_EQ(tuple->u.tuple.fields->size(), 0);
|
||||
@@ -35,7 +35,7 @@ TEST(ParenContentsTest, UnaryNoCommaAsExpression) {
|
||||
ParenContents contents({{.expression = MakeInt(/*line_num=*/2, 42)}},
|
||||
ParenContents::HasTrailingComma::No);
|
||||
|
||||
Expression* expression = contents.AsExpression(/*line_num=*/1);
|
||||
const Expression* expression = contents.AsExpression(/*line_num=*/1);
|
||||
EXPECT_EQ(expression->line_num, 2);
|
||||
ASSERT_EQ(expression->tag, ExpressionKind::Integer);
|
||||
}
|
||||
@@ -44,10 +44,10 @@ TEST(ParenContentsTest, UnaryNoCommaAsTuple) {
|
||||
ParenContents contents({{.expression = MakeInt(/*line_num=*/2, 42)}},
|
||||
ParenContents::HasTrailingComma::No);
|
||||
|
||||
Expression* tuple = contents.AsTuple(/*line_num=*/1);
|
||||
const Expression* tuple = contents.AsTuple(/*line_num=*/1);
|
||||
EXPECT_EQ(tuple->line_num, 1);
|
||||
ASSERT_EQ(tuple->tag, ExpressionKind::Tuple);
|
||||
std::vector<std::pair<std::string, Expression*>> fields =
|
||||
std::vector<std::pair<std::string, const Expression*>> fields =
|
||||
*tuple->u.tuple.fields;
|
||||
ASSERT_EQ(fields.size(), 1);
|
||||
EXPECT_EQ(fields[0].second->tag, ExpressionKind::Integer);
|
||||
@@ -57,10 +57,10 @@ TEST(ParenContentsTest, UnaryWithCommaAsExpression) {
|
||||
ParenContents contents({{.expression = MakeInt(/*line_num=*/2, 42)}},
|
||||
ParenContents::HasTrailingComma::Yes);
|
||||
|
||||
Expression* expression = contents.AsExpression(/*line_num=*/1);
|
||||
const Expression* expression = contents.AsExpression(/*line_num=*/1);
|
||||
EXPECT_EQ(expression->line_num, 1);
|
||||
ASSERT_EQ(expression->tag, ExpressionKind::Tuple);
|
||||
std::vector<std::pair<std::string, Expression*>> fields =
|
||||
std::vector<std::pair<std::string, const Expression*>> fields =
|
||||
*expression->u.tuple.fields;
|
||||
ASSERT_EQ(fields.size(), 1);
|
||||
EXPECT_EQ(fields[0].second->tag, ExpressionKind::Integer);
|
||||
@@ -70,10 +70,10 @@ TEST(ParenContentsTest, UnaryWithCommaAsTuple) {
|
||||
ParenContents contents({{.expression = MakeInt(/*line_num=*/2, 42)}},
|
||||
ParenContents::HasTrailingComma::Yes);
|
||||
|
||||
Expression* tuple = contents.AsTuple(/*line_num=*/1);
|
||||
const Expression* tuple = contents.AsTuple(/*line_num=*/1);
|
||||
EXPECT_EQ(tuple->line_num, 1);
|
||||
ASSERT_EQ(tuple->tag, ExpressionKind::Tuple);
|
||||
std::vector<std::pair<std::string, Expression*>> fields =
|
||||
std::vector<std::pair<std::string, const Expression*>> fields =
|
||||
*tuple->u.tuple.fields;
|
||||
ASSERT_EQ(fields.size(), 1);
|
||||
EXPECT_EQ(fields[0].second->tag, ExpressionKind::Integer);
|
||||
@@ -84,10 +84,10 @@ TEST(ParenContentsTest, BinaryAsExpression) {
|
||||
{.expression = MakeInt(/*line_num=*/3, 42)}},
|
||||
ParenContents::HasTrailingComma::Yes);
|
||||
|
||||
Expression* expression = contents.AsExpression(/*line_num=*/1);
|
||||
const Expression* expression = contents.AsExpression(/*line_num=*/1);
|
||||
EXPECT_EQ(expression->line_num, 1);
|
||||
ASSERT_EQ(expression->tag, ExpressionKind::Tuple);
|
||||
std::vector<std::pair<std::string, Expression*>> fields =
|
||||
std::vector<std::pair<std::string, const Expression*>> fields =
|
||||
*expression->u.tuple.fields;
|
||||
ASSERT_EQ(fields.size(), 2);
|
||||
EXPECT_EQ(fields[0].second->tag, ExpressionKind::Integer);
|
||||
@@ -99,10 +99,10 @@ TEST(ParenContentsTest, BinaryAsTuple) {
|
||||
{.expression = MakeInt(/*line_num=*/3, 42)}},
|
||||
ParenContents::HasTrailingComma::Yes);
|
||||
|
||||
Expression* tuple = contents.AsTuple(/*line_num=*/1);
|
||||
const Expression* tuple = contents.AsTuple(/*line_num=*/1);
|
||||
EXPECT_EQ(tuple->line_num, 1);
|
||||
ASSERT_EQ(tuple->tag, ExpressionKind::Tuple);
|
||||
std::vector<std::pair<std::string, Expression*>> fields =
|
||||
std::vector<std::pair<std::string, const Expression*>> fields =
|
||||
*tuple->u.tuple.fields;
|
||||
ASSERT_EQ(fields.size(), 2);
|
||||
EXPECT_EQ(fields[0].second->tag, ExpressionKind::Integer);
|
||||
|
||||
@@ -96,24 +96,24 @@ void yy::parser::error(
|
||||
%type <Carbon::FunctionDefinition*> function_declaration
|
||||
%type <Carbon::FunctionDefinition*> function_definition
|
||||
%type <std::list<Carbon::Declaration>*> declaration_list
|
||||
%type <Carbon::Statement*> statement
|
||||
%type <Carbon::Statement*> optional_else
|
||||
%type <Carbon::Statement*> statement_list
|
||||
%type <Carbon::Expression*> expression
|
||||
%type <Carbon::Expression*> pattern
|
||||
%type <Carbon::Expression*> return_type
|
||||
%type <Carbon::Expression*> paren_expression
|
||||
%type <Carbon::Expression*> tuple
|
||||
%type <const Carbon::Statement*> statement
|
||||
%type <const Carbon::Statement*> optional_else
|
||||
%type <const Carbon::Statement*> statement_list
|
||||
%type <const Carbon::Expression*> expression
|
||||
%type <const Carbon::Expression*> pattern
|
||||
%type <const Carbon::Expression*> return_type
|
||||
%type <const Carbon::Expression*> paren_expression
|
||||
%type <const Carbon::Expression*> tuple
|
||||
%type <Carbon::Member*> variable_declaration
|
||||
%type <Carbon::Member*> member
|
||||
%type <std::list<Carbon::Member*>*> member_list
|
||||
%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<Carbon::Expression*, Carbon::Statement*>*> clause
|
||||
%type <std::list<std::pair<Carbon::Expression*, Carbon::Statement*>>*> clause_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
|
||||
%token AND
|
||||
%token OR
|
||||
@@ -266,18 +266,18 @@ paren_contents_without_trailing_comma:
|
||||
;
|
||||
clause:
|
||||
CASE pattern DBLARROW statement
|
||||
{ $$ = new std::pair<Carbon::Expression*, Carbon::Statement*>($2, $4); }
|
||||
{ $$ = new std::pair<const Carbon::Expression*, const Carbon::Statement*>($2, $4); }
|
||||
| DEFAULT DBLARROW statement
|
||||
{
|
||||
auto vp = Carbon::MakeVarPat(yylineno, "_",
|
||||
Carbon::MakeAutoType(yylineno));
|
||||
$$ = new std::pair<Carbon::Expression*, Carbon::Statement*>(vp, $3);
|
||||
$$ = new std::pair<const Carbon::Expression*, const Carbon::Statement*>(vp, $3);
|
||||
}
|
||||
;
|
||||
clause_list:
|
||||
// Empty
|
||||
{
|
||||
$$ = new std::list<std::pair<Carbon::Expression*, Carbon::Statement*>>();
|
||||
$$ = new std::list<std::pair<const Carbon::Expression*, const Carbon::Statement*>>();
|
||||
}
|
||||
| clause clause_list
|
||||
{ $$ = $2; $$->push_front(*$1); }
|
||||
@@ -326,7 +326,7 @@ return_type:
|
||||
{
|
||||
$$ = Carbon::MakeTuple(
|
||||
yylineno,
|
||||
new std::vector<std::pair<std::string, Carbon::Expression*>>());
|
||||
new std::vector<std::pair<std::string, const Carbon::Expression*>>());
|
||||
}
|
||||
| ARROW expression
|
||||
{ $$ = $2; }
|
||||
@@ -358,21 +358,21 @@ member_list:
|
||||
;
|
||||
alternative:
|
||||
identifier tuple
|
||||
{ $$ = new std::pair<std::string, Carbon::Expression*>($1, $2); }
|
||||
{ $$ = new std::pair<std::string, const Carbon::Expression*>($1, $2); }
|
||||
| identifier
|
||||
{
|
||||
$$ = new std::pair<std::string, Carbon::Expression*>(
|
||||
$$ = new std::pair<std::string, const Carbon::Expression*>(
|
||||
$1, Carbon::MakeTuple(
|
||||
yylineno,
|
||||
new std::vector<std::pair<std::string, Carbon::Expression*>>()));
|
||||
new std::vector<std::pair<std::string, const Carbon::Expression*>>()));
|
||||
}
|
||||
;
|
||||
alternative_list:
|
||||
// Empty
|
||||
{ $$ = new std::list<std::pair<std::string, Carbon::Expression*>>(); }
|
||||
{ $$ = new std::list<std::pair<std::string, const Carbon::Expression*>>(); }
|
||||
| alternative
|
||||
{
|
||||
$$ = new std::list<std::pair<std::string, Carbon::Expression*>>();
|
||||
$$ = new std::list<std::pair<std::string, const Carbon::Expression*>>();
|
||||
$$->push_front(*$1);
|
||||
}
|
||||
| alternative "," alternative_list
|
||||
|
||||
Reference in New Issue
Block a user