mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Move all new's to global_arena, and remove ASAN disabling (#690)
Note this changes identifiers from char* to string to avoid malloc. Fixes #580
This commit is contained in:
@@ -26,10 +26,6 @@ cc_binary(
|
||||
":executable_semantics",
|
||||
"testdata/%s.carbon" % e,
|
||||
],
|
||||
env = {
|
||||
# TODO(#580): Remove this when leaks are fixed.
|
||||
"ASAN_OPTIONS": "detect_leaks=0",
|
||||
},
|
||||
golden = "testdata/%s.golden" % e,
|
||||
) for e in TEST_LIST]
|
||||
|
||||
@@ -49,10 +45,6 @@ test_suite(
|
||||
":executable_semantics",
|
||||
"testdata/%s.carbon" % e,
|
||||
],
|
||||
env = {
|
||||
# TODO(#580): Remove this when leaks are fixed.
|
||||
"ASAN_OPTIONS": "detect_leaks=0",
|
||||
},
|
||||
golden = "testdata/%s.golden" % e,
|
||||
golden_is_subset = True,
|
||||
) for e in TEST_LIST]
|
||||
|
||||
@@ -42,10 +42,6 @@ cc_library(
|
||||
cc_test(
|
||||
name = "expression_test",
|
||||
srcs = ["expression_test.cpp"],
|
||||
env = {
|
||||
# TODO(#580): Remove this when leaks are fixed.
|
||||
"ASAN_OPTIONS": "detect_leaks=0",
|
||||
},
|
||||
deps = [
|
||||
":expression",
|
||||
"//executable_semantics/syntax:paren_contents",
|
||||
@@ -82,6 +78,7 @@ cc_library(
|
||||
deps = [
|
||||
":expression",
|
||||
"//common:ostream",
|
||||
"//executable_semantics/common:arena",
|
||||
"//executable_semantics/common:error",
|
||||
"@llvm-project//llvm:Support",
|
||||
],
|
||||
@@ -90,10 +87,6 @@ cc_library(
|
||||
cc_test(
|
||||
name = "pattern_test",
|
||||
srcs = ["pattern_test.cpp"],
|
||||
env = {
|
||||
# TODO(#580): Remove this when leaks are fixed.
|
||||
"ASAN_OPTIONS": "detect_leaks=0",
|
||||
},
|
||||
deps = [
|
||||
":pattern",
|
||||
"//executable_semantics/syntax:paren_contents",
|
||||
@@ -112,6 +105,7 @@ cc_library(
|
||||
":pattern",
|
||||
"//common:check",
|
||||
"//common:ostream",
|
||||
"//executable_semantics/common:arena",
|
||||
"@llvm-project//llvm:Support",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -4,11 +4,13 @@
|
||||
|
||||
#include "executable_semantics/ast/member.h"
|
||||
|
||||
#include "executable_semantics/common/arena.h"
|
||||
|
||||
namespace Carbon {
|
||||
|
||||
auto Member::MakeFieldMember(int line_num, const BindingPattern* binding)
|
||||
-> Member* {
|
||||
auto m = new Member();
|
||||
auto m = global_arena->New<Member>();
|
||||
m->line_num = line_num;
|
||||
m->value = FieldMember({.binding = binding});
|
||||
return m;
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include "common/ostream.h"
|
||||
#include "executable_semantics/ast/expression.h"
|
||||
#include "executable_semantics/common/arena.h"
|
||||
#include "executable_semantics/common/error.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
@@ -57,7 +58,8 @@ TuplePattern::TuplePattern(const Expression* tuple_literal)
|
||||
: Pattern(Kind::TuplePattern, tuple_literal->line_num) {
|
||||
const auto& tuple = tuple_literal->GetTupleLiteral();
|
||||
for (const FieldInitializer& init : tuple.fields) {
|
||||
fields.push_back(Field(init.name, new ExpressionPattern(init.expression)));
|
||||
fields.push_back(Field(
|
||||
init.name, global_arena->New<ExpressionPattern>(init.expression)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,7 +77,7 @@ auto PatternFromParenContents(int line_num,
|
||||
auto TuplePatternFromParenContents(int line_num,
|
||||
const ParenContents<Pattern>& paren_contents)
|
||||
-> const TuplePattern* {
|
||||
return new TuplePattern(
|
||||
return global_arena->New<TuplePattern>(
|
||||
line_num, paren_contents.TupleElements<TuplePattern::Field>(line_num));
|
||||
}
|
||||
|
||||
@@ -98,7 +100,8 @@ auto ParenExpressionToParenPattern(const ParenContents<Expression>& contents)
|
||||
.elements = {}, .has_trailing_comma = contents.has_trailing_comma};
|
||||
for (const auto& element : contents.elements) {
|
||||
result.elements.push_back(
|
||||
{.name = element.name, .term = new ExpressionPattern(element.term)});
|
||||
{.name = element.name,
|
||||
.term = global_arena->New<ExpressionPattern>(element.term)});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "executable_semantics/ast/pattern.h"
|
||||
|
||||
#include "executable_semantics/ast/expression.h"
|
||||
#include "executable_semantics/common/arena.h"
|
||||
#include "executable_semantics/syntax/paren_contents.h"
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
@@ -51,7 +52,7 @@ TEST(PatternTest, UnaryNoCommaAsPattern) {
|
||||
// ```
|
||||
ParenContents<Pattern> contents = {
|
||||
.elements = {{.name = std::nullopt,
|
||||
.term = new AutoPattern(/*line_num=*/2)}},
|
||||
.term = global_arena->New<AutoPattern>(/*line_num=*/2)}},
|
||||
.has_trailing_comma = false};
|
||||
|
||||
const Pattern* pattern = PatternFromParenContents(/*line_num=*/1, contents);
|
||||
@@ -62,7 +63,7 @@ TEST(PatternTest, UnaryNoCommaAsPattern) {
|
||||
TEST(PatternTest, UnaryNoCommaAsTuplePattern) {
|
||||
ParenContents<Pattern> contents = {
|
||||
.elements = {{.name = std::nullopt,
|
||||
.term = new AutoPattern(/*line_num=*/2)}},
|
||||
.term = global_arena->New<AutoPattern>(/*line_num=*/2)}},
|
||||
.has_trailing_comma = false};
|
||||
|
||||
const TuplePattern* tuple =
|
||||
@@ -74,7 +75,7 @@ TEST(PatternTest, UnaryNoCommaAsTuplePattern) {
|
||||
TEST(PatternTest, UnaryWithCommaAsPattern) {
|
||||
ParenContents<Pattern> contents = {
|
||||
.elements = {{.name = std::nullopt,
|
||||
.term = new AutoPattern(/*line_num=*/2)}},
|
||||
.term = global_arena->New<AutoPattern>(/*line_num=*/2)}},
|
||||
.has_trailing_comma = true};
|
||||
|
||||
const Pattern* pattern = PatternFromParenContents(/*line_num=*/1, contents);
|
||||
@@ -87,7 +88,7 @@ TEST(PatternTest, UnaryWithCommaAsPattern) {
|
||||
TEST(PatternTest, UnaryWithCommaAsTuplePattern) {
|
||||
ParenContents<Pattern> contents = {
|
||||
.elements = {{.name = std::nullopt,
|
||||
.term = new AutoPattern(/*line_num=*/2)}},
|
||||
.term = global_arena->New<AutoPattern>(/*line_num=*/2)}},
|
||||
.has_trailing_comma = true};
|
||||
|
||||
const TuplePattern* tuple =
|
||||
@@ -99,9 +100,9 @@ TEST(PatternTest, UnaryWithCommaAsTuplePattern) {
|
||||
TEST(PatternTest, BinaryAsPattern) {
|
||||
ParenContents<Pattern> contents = {
|
||||
.elements = {{.name = std::nullopt,
|
||||
.term = new AutoPattern(/*line_num=*/2)},
|
||||
.term = global_arena->New<AutoPattern>(/*line_num=*/2)},
|
||||
{.name = std::nullopt,
|
||||
.term = new AutoPattern(/*line_num=*/3)}},
|
||||
.term = global_arena->New<AutoPattern>(/*line_num=*/3)}},
|
||||
.has_trailing_comma = true};
|
||||
|
||||
const Pattern* pattern = PatternFromParenContents(/*line_num=*/1, contents);
|
||||
@@ -114,9 +115,9 @@ TEST(PatternTest, BinaryAsPattern) {
|
||||
TEST(PatternTest, BinaryAsTuplePattern) {
|
||||
ParenContents<Pattern> contents = {
|
||||
.elements = {{.name = std::nullopt,
|
||||
.term = new AutoPattern(/*line_num=*/2)},
|
||||
.term = global_arena->New<AutoPattern>(/*line_num=*/2)},
|
||||
{.name = std::nullopt,
|
||||
.term = new AutoPattern(/*line_num=*/3)}},
|
||||
.term = global_arena->New<AutoPattern>(/*line_num=*/3)}},
|
||||
.has_trailing_comma = true};
|
||||
|
||||
const TuplePattern* tuple =
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "executable_semantics/ast/statement.h"
|
||||
|
||||
#include "common/check.h"
|
||||
#include "executable_semantics/common/arena.h"
|
||||
|
||||
namespace Carbon {
|
||||
|
||||
@@ -62,7 +63,7 @@ auto Statement::GetAwait() const -> const Await& {
|
||||
|
||||
auto Statement::MakeExpressionStatement(int line_num, const Expression* exp)
|
||||
-> const Statement* {
|
||||
auto* s = new Statement();
|
||||
auto* s = global_arena->New<Statement>();
|
||||
s->line_num = line_num;
|
||||
s->value = ExpressionStatement({.exp = exp});
|
||||
return s;
|
||||
@@ -70,7 +71,7 @@ auto Statement::MakeExpressionStatement(int line_num, const Expression* exp)
|
||||
|
||||
auto Statement::MakeAssign(int line_num, const Expression* lhs,
|
||||
const Expression* rhs) -> const Statement* {
|
||||
auto* s = new Statement();
|
||||
auto* s = global_arena->New<Statement>();
|
||||
s->line_num = line_num;
|
||||
s->value = Assign({.lhs = lhs, .rhs = rhs});
|
||||
return s;
|
||||
@@ -79,7 +80,7 @@ auto Statement::MakeAssign(int line_num, const Expression* lhs,
|
||||
auto Statement::MakeVariableDefinition(int line_num, const Pattern* pat,
|
||||
const Expression* init)
|
||||
-> const Statement* {
|
||||
auto* s = new Statement();
|
||||
auto* s = global_arena->New<Statement>();
|
||||
s->line_num = line_num;
|
||||
s->value = VariableDefinition({.pat = pat, .init = init});
|
||||
return s;
|
||||
@@ -88,7 +89,7 @@ auto Statement::MakeVariableDefinition(int line_num, const Pattern* pat,
|
||||
auto Statement::MakeIf(int line_num, const Expression* cond,
|
||||
const Statement* then_stmt, const Statement* else_stmt)
|
||||
-> const Statement* {
|
||||
auto* s = new Statement();
|
||||
auto* s = global_arena->New<Statement>();
|
||||
s->line_num = line_num;
|
||||
s->value = If({.cond = cond, .then_stmt = then_stmt, .else_stmt = else_stmt});
|
||||
return s;
|
||||
@@ -96,21 +97,21 @@ auto Statement::MakeIf(int line_num, const Expression* cond,
|
||||
|
||||
auto Statement::MakeWhile(int line_num, const Expression* cond,
|
||||
const Statement* body) -> const Statement* {
|
||||
auto* s = new Statement();
|
||||
auto* s = global_arena->New<Statement>();
|
||||
s->line_num = line_num;
|
||||
s->value = While({.cond = cond, .body = body});
|
||||
return s;
|
||||
}
|
||||
|
||||
auto Statement::MakeBreak(int line_num) -> const Statement* {
|
||||
auto* s = new Statement();
|
||||
auto* s = global_arena->New<Statement>();
|
||||
s->line_num = line_num;
|
||||
s->value = Break();
|
||||
return s;
|
||||
}
|
||||
|
||||
auto Statement::MakeContinue(int line_num) -> const Statement* {
|
||||
auto* s = new Statement();
|
||||
auto* s = global_arena->New<Statement>();
|
||||
s->line_num = line_num;
|
||||
s->value = Continue();
|
||||
return s;
|
||||
@@ -118,7 +119,7 @@ auto Statement::MakeContinue(int line_num) -> const Statement* {
|
||||
|
||||
auto Statement::MakeReturn(int line_num, const Expression* e)
|
||||
-> const Statement* {
|
||||
auto* s = new Statement();
|
||||
auto* s = global_arena->New<Statement>();
|
||||
s->line_num = line_num;
|
||||
s->value = Return({.exp = e});
|
||||
return s;
|
||||
@@ -126,7 +127,7 @@ auto Statement::MakeReturn(int line_num, const Expression* e)
|
||||
|
||||
auto Statement::MakeSequence(int line_num, const Statement* s1,
|
||||
const Statement* s2) -> const Statement* {
|
||||
auto* s = new Statement();
|
||||
auto* s = global_arena->New<Statement>();
|
||||
s->line_num = line_num;
|
||||
s->value = Sequence({.stmt = s1, .next = s2});
|
||||
return s;
|
||||
@@ -134,7 +135,7 @@ auto Statement::MakeSequence(int line_num, const Statement* s1,
|
||||
|
||||
auto Statement::MakeBlock(int line_num, const Statement* stmt)
|
||||
-> const Statement* {
|
||||
auto* s = new Statement();
|
||||
auto* s = global_arena->New<Statement>();
|
||||
s->line_num = line_num;
|
||||
s->value = Block({.stmt = stmt});
|
||||
return s;
|
||||
@@ -144,7 +145,7 @@ auto Statement::MakeMatch(
|
||||
int line_num, const Expression* exp,
|
||||
std::list<std::pair<const Pattern*, const Statement*>>* clauses)
|
||||
-> const Statement* {
|
||||
auto* s = new Statement();
|
||||
auto* s = global_arena->New<Statement>();
|
||||
s->line_num = line_num;
|
||||
s->value = Match({.exp = exp, .clauses = clauses});
|
||||
return s;
|
||||
@@ -155,7 +156,7 @@ auto Statement::MakeMatch(
|
||||
auto Statement::MakeContinuation(int line_num,
|
||||
std::string continuation_variable,
|
||||
const Statement* body) -> const Statement* {
|
||||
auto* s = new Statement();
|
||||
auto* s = global_arena->New<Statement>();
|
||||
s->line_num = line_num;
|
||||
s->value =
|
||||
Continuation({.continuation_variable = std::move(continuation_variable),
|
||||
@@ -166,7 +167,7 @@ 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, const Expression* argument)
|
||||
-> const Statement* {
|
||||
auto* s = new Statement();
|
||||
auto* s = global_arena->New<Statement>();
|
||||
s->line_num = line_num;
|
||||
s->value = Run({.argument = argument});
|
||||
return s;
|
||||
@@ -174,7 +175,7 @@ auto Statement::MakeRun(int line_num, const Expression* argument)
|
||||
|
||||
// Returns an AST node for an await statement give its line number.
|
||||
auto Statement::MakeAwait(int line_num) -> const Statement* {
|
||||
auto* s = new Statement();
|
||||
auto* s = global_arena->New<Statement>();
|
||||
s->line_num = line_num;
|
||||
s->value = Await();
|
||||
return s;
|
||||
|
||||
@@ -37,7 +37,7 @@ class Arena {
|
||||
class ArenaEntryTyped : public ArenaEntry {
|
||||
public:
|
||||
template <typename... Args>
|
||||
explicit ArenaEntryTyped(Args&... args)
|
||||
explicit ArenaEntryTyped(Args&&... args)
|
||||
: instance(std::forward<Args>(args)...) {}
|
||||
|
||||
auto Instance() -> T* { return &instance; }
|
||||
|
||||
@@ -17,6 +17,7 @@ cc_library(
|
||||
"//executable_semantics/ast:expression",
|
||||
"//executable_semantics/ast:function_definition",
|
||||
"//executable_semantics/ast:statement",
|
||||
"//executable_semantics/common:arena",
|
||||
"@llvm-project//llvm:Support",
|
||||
],
|
||||
)
|
||||
@@ -97,6 +98,7 @@ cc_library(
|
||||
"//executable_semantics/ast:declaration",
|
||||
"//executable_semantics/ast:expression",
|
||||
"//executable_semantics/ast:function_definition",
|
||||
"//executable_semantics/common:arena",
|
||||
"//executable_semantics/common:tracing_flag",
|
||||
"@llvm-project//llvm:Support",
|
||||
],
|
||||
@@ -113,6 +115,7 @@ cc_library(
|
||||
"//executable_semantics/ast:expression",
|
||||
"//executable_semantics/ast:function_definition",
|
||||
"//executable_semantics/ast:statement",
|
||||
"//executable_semantics/common:arena",
|
||||
"//executable_semantics/common:tracing_flag",
|
||||
"@llvm-project//llvm:Support",
|
||||
],
|
||||
@@ -129,6 +132,8 @@ cc_library(
|
||||
"//common:ostream",
|
||||
"//executable_semantics/ast:function_definition",
|
||||
"//executable_semantics/ast:statement",
|
||||
"//executable_semantics/common:arena",
|
||||
"//executable_semantics/common:error",
|
||||
"@llvm-project//llvm:Support",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -12,37 +12,38 @@
|
||||
|
||||
#include "executable_semantics/ast/expression.h"
|
||||
#include "executable_semantics/ast/function_definition.h"
|
||||
#include "executable_semantics/common/arena.h"
|
||||
#include "executable_semantics/interpreter/stack.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
|
||||
namespace Carbon {
|
||||
|
||||
auto Action::MakeLValAction(const Expression* e) -> Action* {
|
||||
auto* act = new Action();
|
||||
auto* act = global_arena->New<Action>();
|
||||
act->value = LValAction({.exp = e});
|
||||
return act;
|
||||
}
|
||||
|
||||
auto Action::MakeExpressionAction(const Expression* e) -> Action* {
|
||||
auto* act = new Action();
|
||||
auto* act = global_arena->New<Action>();
|
||||
act->value = ExpressionAction({.exp = e});
|
||||
return act;
|
||||
}
|
||||
|
||||
auto Action::MakePatternAction(const Pattern* p) -> Action* {
|
||||
auto* act = new Action();
|
||||
auto* act = global_arena->New<Action>();
|
||||
act->value = PatternAction({.pattern = p});
|
||||
return act;
|
||||
}
|
||||
|
||||
auto Action::MakeStatementAction(const Statement* s) -> Action* {
|
||||
auto* act = new Action();
|
||||
auto* act = global_arena->New<Action>();
|
||||
act->value = StatementAction({.stmt = s});
|
||||
return act;
|
||||
}
|
||||
|
||||
auto Action::MakeValAction(const Value* v) -> Action* {
|
||||
auto* act = new Action();
|
||||
auto* act = global_arena->New<Action>();
|
||||
act->value = ValAction({.val = v});
|
||||
return act;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include "executable_semantics/common/arena.h"
|
||||
#include "executable_semantics/interpreter/list_node.h"
|
||||
|
||||
namespace Carbon {
|
||||
@@ -37,7 +38,8 @@ class Dictionary {
|
||||
// Associate the value v with key k in the dictionary.
|
||||
// Time complexity: O(1).
|
||||
auto Set(const K& k, const V& v) -> void {
|
||||
head = new ListNode<std::pair<K, V>>(std::make_pair(k, v), head);
|
||||
head = global_arena->New<ListNode<std::pair<K, V>>>(std::make_pair(k, v),
|
||||
head);
|
||||
}
|
||||
|
||||
typedef ListNodeIterator<std::pair<K, V>> Iterator;
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "common/check.h"
|
||||
#include "executable_semantics/ast/expression.h"
|
||||
#include "executable_semantics/ast/function_definition.h"
|
||||
#include "executable_semantics/common/arena.h"
|
||||
#include "executable_semantics/common/error.h"
|
||||
#include "executable_semantics/common/tracing_flag.h"
|
||||
#include "executable_semantics/interpreter/action.h"
|
||||
@@ -193,10 +194,11 @@ void CallFunction(int line_num, std::vector<const Value*> operas,
|
||||
¶ms, line_num);
|
||||
CHECK(matches) << "internal error in call_function, pattern match failed";
|
||||
// Create the new frame and push it on the stack
|
||||
auto* scope = new Scope(*matches, params);
|
||||
auto* frame = new Frame(operas[0]->GetFunctionValue().name, Stack(scope),
|
||||
Stack(Action::MakeStatementAction(
|
||||
operas[0]->GetFunctionValue().body)));
|
||||
auto* scope = global_arena->New<Scope>(*matches, params);
|
||||
auto* frame = global_arena->New<Frame>(
|
||||
operas[0]->GetFunctionValue().name, Stack(scope),
|
||||
Stack(
|
||||
Action::MakeStatementAction(operas[0]->GetFunctionValue().body)));
|
||||
state->stack.Push(frame);
|
||||
break;
|
||||
}
|
||||
@@ -888,7 +890,7 @@ void StepStmt() {
|
||||
std::optional<Env> matches =
|
||||
PatternMatch(pat, v, values, &vars, stmt->line_num);
|
||||
if (matches) { // we have a match, start the body
|
||||
auto* new_scope = new Scope(*matches, vars);
|
||||
auto* new_scope = global_arena->New<Scope>(*matches, vars);
|
||||
frame->scopes.Push(new_scope);
|
||||
const Statement* body_block =
|
||||
Statement::MakeBlock(stmt->line_num, c->second);
|
||||
@@ -959,7 +961,8 @@ void StepStmt() {
|
||||
case StatementKind::Block: {
|
||||
if (act->pos == 0) {
|
||||
if (stmt->GetBlock().stmt) {
|
||||
auto* scope = new Scope(CurrentEnv(state), {});
|
||||
auto* scope = global_arena->New<Scope>(CurrentEnv(state),
|
||||
std::list<std::string>());
|
||||
frame->scopes.Push(scope);
|
||||
frame->todo.Push(Action::MakeStatementAction(stmt->GetBlock().stmt));
|
||||
act->pos++;
|
||||
@@ -1085,14 +1088,16 @@ void StepStmt() {
|
||||
CHECK(act->pos == 0);
|
||||
// Create a continuation object by creating a frame similar the
|
||||
// way one is created in a function call.
|
||||
Scope* scope = new Scope(CurrentEnv(state), std::list<std::string>());
|
||||
Scope* scope =
|
||||
global_arena->New<Scope>(CurrentEnv(state), std::list<std::string>());
|
||||
Stack<Scope*> scopes;
|
||||
scopes.Push(scope);
|
||||
Stack<Action*> todo;
|
||||
todo.Push(Action::MakeStatementAction(Statement::MakeReturn(
|
||||
stmt->line_num, Expression::MakeTupleLiteral(stmt->line_num, {}))));
|
||||
todo.Push(Action::MakeStatementAction(stmt->GetContinuation().body));
|
||||
Frame* continuation_frame = new Frame("__continuation", scopes, todo);
|
||||
Frame* continuation_frame =
|
||||
global_arena->New<Frame>("__continuation", scopes, todo);
|
||||
Address continuation_address = state->heap.AllocateValue(
|
||||
Value::MakeContinuationValue({continuation_frame}));
|
||||
// Store the continuation's address in the frame.
|
||||
@@ -1176,7 +1181,7 @@ void Step() {
|
||||
|
||||
// Interpret the whole porogram.
|
||||
auto InterpProgram(std::list<Declaration>* fs) -> int {
|
||||
state = new State(); // Runtime state.
|
||||
state = global_arena->New<State>(); // Runtime state.
|
||||
if (tracing_output) {
|
||||
llvm::outs() << "********** initializing globals **********\n";
|
||||
}
|
||||
@@ -1186,8 +1191,8 @@ auto InterpProgram(std::list<Declaration>* fs) -> int {
|
||||
const Expression* call_main = Expression::MakeCallExpression(
|
||||
0, Expression::MakeIdentifierExpression(0, "main"), arg);
|
||||
auto todo = Stack(Action::MakeExpressionAction(call_main));
|
||||
auto* scope = new Scope(globals, std::list<std::string>());
|
||||
auto* frame = new Frame("top", Stack(scope), todo);
|
||||
auto* scope = global_arena->New<Scope>(globals, std::list<std::string>());
|
||||
auto* frame = global_arena->New<Frame>("top", Stack(scope), todo);
|
||||
state->stack = Stack(frame);
|
||||
|
||||
if (tracing_output) {
|
||||
@@ -1209,8 +1214,8 @@ auto InterpProgram(std::list<Declaration>* fs) -> int {
|
||||
// Interpret an expression at compile-time.
|
||||
auto InterpExp(Env values, const Expression* e) -> const Value* {
|
||||
auto todo = Stack(Action::MakeExpressionAction(e));
|
||||
auto* scope = new Scope(values, std::list<std::string>());
|
||||
auto* frame = new Frame("InterpExp", Stack(scope), todo);
|
||||
auto* scope = global_arena->New<Scope>(values, std::list<std::string>());
|
||||
auto* frame = global_arena->New<Frame>("InterpExp", Stack(scope), todo);
|
||||
state->stack = Stack(frame);
|
||||
|
||||
while (state->stack.Count() > 1 || state->stack.Top()->todo.Count() > 1 ||
|
||||
@@ -1224,8 +1229,8 @@ auto InterpExp(Env values, const Expression* e) -> const Value* {
|
||||
// Interpret a pattern at compile-time.
|
||||
auto InterpPattern(Env values, const Pattern* p) -> const Value* {
|
||||
auto todo = Stack(Action::MakePatternAction(p));
|
||||
auto* scope = new Scope(values, std::list<std::string>());
|
||||
auto* frame = new Frame("InterpPattern", Stack(scope), todo);
|
||||
auto* scope = global_arena->New<Scope>(values, std::list<std::string>());
|
||||
auto* frame = global_arena->New<Frame>("InterpPattern", Stack(scope), todo);
|
||||
state->stack = Stack(frame);
|
||||
|
||||
while (state->stack.Count() > 1 || state->stack.Top()->todo.Count() > 1 ||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#include "common/ostream.h"
|
||||
#include "executable_semantics/ast/function_definition.h"
|
||||
#include "executable_semantics/common/arena.h"
|
||||
#include "executable_semantics/common/error.h"
|
||||
#include "executable_semantics/common/tracing_flag.h"
|
||||
#include "executable_semantics/interpreter/interpreter.h"
|
||||
@@ -512,9 +513,10 @@ auto TypeCheckPattern(const Pattern* p, TypeEnv types, Env values,
|
||||
FATAL_COMPILATION_ERROR(binding.LineNumber())
|
||||
<< "Unsupported type pattern";
|
||||
}
|
||||
auto new_p = new BindingPattern(
|
||||
auto new_p = global_arena->New<BindingPattern>(
|
||||
binding.LineNumber(), binding.Name(),
|
||||
new ExpressionPattern(ReifyType(type, binding.LineNumber())));
|
||||
global_arena->New<ExpressionPattern>(
|
||||
ReifyType(type, binding.LineNumber())));
|
||||
if (binding.Name().has_value()) {
|
||||
types.Set(*binding.Name(), type);
|
||||
}
|
||||
@@ -553,7 +555,8 @@ auto TypeCheckPattern(const Pattern* p, TypeEnv types, Env values,
|
||||
TuplePattern::Field(field.name, field_result.pattern));
|
||||
field_types.push_back({.name = field.name, .value = field_result.type});
|
||||
}
|
||||
auto new_tuple = new TuplePattern(tuple.LineNumber(), new_fields);
|
||||
auto new_tuple =
|
||||
global_arena->New<TuplePattern>(tuple.LineNumber(), new_fields);
|
||||
auto tuple_t = Value::MakeTupleValue(std::move(field_types));
|
||||
return {.pattern = new_tuple, .type = tuple_t, .types = new_types};
|
||||
}
|
||||
@@ -578,7 +581,7 @@ auto TypeCheckPattern(const Pattern* p, TypeEnv types, Env values,
|
||||
}
|
||||
TCPattern arg_results = TypeCheckPattern(alternative.Arguments(), types,
|
||||
values, parameter_types);
|
||||
return {.pattern = new AlternativePattern(
|
||||
return {.pattern = global_arena->New<AlternativePattern>(
|
||||
alternative.LineNumber(),
|
||||
ReifyType(choice_type, alternative.LineNumber()),
|
||||
alternative.AlternativeName(),
|
||||
@@ -589,7 +592,7 @@ auto TypeCheckPattern(const Pattern* p, TypeEnv types, Env values,
|
||||
case Pattern::Kind::ExpressionPattern: {
|
||||
TCExpression result =
|
||||
TypeCheckExp(cast<ExpressionPattern>(p)->Expression(), types, values);
|
||||
return {.pattern = new ExpressionPattern(result.exp),
|
||||
return {.pattern = global_arena->New<ExpressionPattern>(result.exp),
|
||||
.type = result.type,
|
||||
.types = result.types};
|
||||
}
|
||||
@@ -622,7 +625,8 @@ auto TypeCheckStmt(const Statement* s, TypeEnv types, Env values,
|
||||
auto res = TypeCheckExp(s->GetMatch().exp, types, values);
|
||||
auto res_type = res.type;
|
||||
auto new_clauses =
|
||||
new std::list<std::pair<const Pattern*, const Statement*>>();
|
||||
global_arena
|
||||
->New<std::list<std::pair<const Pattern*, const Statement*>>>();
|
||||
for (auto& clause : *s->GetMatch().clauses) {
|
||||
new_clauses->push_back(TypecheckCase(
|
||||
res_type, clause.first, clause.second, types, values, ret_type));
|
||||
@@ -748,7 +752,8 @@ auto CheckOrEnsureReturn(const Statement* stmt, bool void_return, int line_num)
|
||||
switch (stmt->tag()) {
|
||||
case StatementKind::Match: {
|
||||
auto new_clauses =
|
||||
new std::list<std::pair<const Pattern*, const Statement*>>();
|
||||
global_arena
|
||||
->New<std::list<std::pair<const Pattern*, const Statement*>>>();
|
||||
for (auto i = stmt->GetMatch().clauses->begin();
|
||||
i != stmt->GetMatch().clauses->end(); ++i) {
|
||||
auto s = CheckOrEnsureReturn(i->second, void_return, stmt->line_num);
|
||||
@@ -827,9 +832,10 @@ auto TypeCheckFunDef(const FunctionDefinition* f, TypeEnv types, Env values)
|
||||
auto res = TypeCheckStmt(f->body, param_res.types, values, return_type);
|
||||
bool void_return = TypeEqual(return_type, Value::MakeUnitTypeVal());
|
||||
auto body = CheckOrEnsureReturn(res.stmt, void_return, f->line_num);
|
||||
return new FunctionDefinition(
|
||||
return global_arena->New<FunctionDefinition>(
|
||||
f->line_num, f->name, f->deduced_parameters, f->param_pattern,
|
||||
new ExpressionPattern(ReifyType(return_type, f->line_num)), body);
|
||||
global_arena->New<ExpressionPattern>(ReifyType(return_type, f->line_num)),
|
||||
body);
|
||||
}
|
||||
|
||||
auto TypeOfFunDef(TypeEnv types, Env values, const FunctionDefinition* fun_def)
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <algorithm>
|
||||
|
||||
#include "common/check.h"
|
||||
#include "executable_semantics/common/arena.h"
|
||||
#include "executable_semantics/common/error.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
|
||||
@@ -111,47 +112,47 @@ auto TupleValue::FindField(const std::string& name) const -> const Value* {
|
||||
}
|
||||
|
||||
auto Value::MakeIntValue(int i) -> const Value* {
|
||||
auto* v = new Value();
|
||||
auto* v = global_arena->New<Value>();
|
||||
v->value = IntValue({.value = i});
|
||||
return v;
|
||||
}
|
||||
|
||||
auto Value::MakeBoolValue(bool b) -> const Value* {
|
||||
auto* v = new Value();
|
||||
auto* v = global_arena->New<Value>();
|
||||
v->value = BoolValue({.value = b});
|
||||
return v;
|
||||
}
|
||||
|
||||
auto Value::MakeFunctionValue(std::string name, const Value* param,
|
||||
const Statement* body) -> const Value* {
|
||||
auto* v = new Value();
|
||||
auto* v = global_arena->New<Value>();
|
||||
v->value =
|
||||
FunctionValue({.name = std::move(name), .param = param, .body = body});
|
||||
return v;
|
||||
}
|
||||
|
||||
auto Value::MakePointerValue(Address addr) -> const Value* {
|
||||
auto* v = new Value();
|
||||
auto* v = global_arena->New<Value>();
|
||||
v->value = PointerValue({.value = addr});
|
||||
return v;
|
||||
}
|
||||
|
||||
auto Value::MakeStructValue(const Value* type, const Value* inits)
|
||||
-> const Value* {
|
||||
auto* v = new Value();
|
||||
auto* v = global_arena->New<Value>();
|
||||
v->value = StructValue({.type = type, .inits = inits});
|
||||
return v;
|
||||
}
|
||||
|
||||
auto Value::MakeTupleValue(std::vector<TupleElement> elements) -> const Value* {
|
||||
auto* v = new Value();
|
||||
auto* v = global_arena->New<Value>();
|
||||
v->value = TupleValue({.elements = std::move(elements)});
|
||||
return v;
|
||||
}
|
||||
|
||||
auto Value::MakeAlternativeValue(std::string alt_name, std::string choice_name,
|
||||
const Value* argument) -> const Value* {
|
||||
auto* v = new Value();
|
||||
auto* v = global_arena->New<Value>();
|
||||
v->value = AlternativeValue({.alt_name = std::move(alt_name),
|
||||
.choice_name = std::move(choice_name),
|
||||
.argument = argument});
|
||||
@@ -161,7 +162,7 @@ auto Value::MakeAlternativeValue(std::string alt_name, std::string choice_name,
|
||||
auto Value::MakeAlternativeConstructorValue(std::string alt_name,
|
||||
std::string choice_name)
|
||||
-> const Value* {
|
||||
auto* v = new Value();
|
||||
auto* v = global_arena->New<Value>();
|
||||
v->value = AlternativeConstructorValue(
|
||||
{.alt_name = std::move(alt_name), .choice_name = std::move(choice_name)});
|
||||
return v;
|
||||
@@ -170,45 +171,45 @@ auto Value::MakeAlternativeConstructorValue(std::string alt_name,
|
||||
// Return a first-class continuation represented a fragment
|
||||
// of the stack.
|
||||
auto Value::MakeContinuationValue(std::vector<Frame*> stack) -> Value* {
|
||||
auto* v = new Value();
|
||||
auto* v = global_arena->New<Value>();
|
||||
v->value = ContinuationValue({.stack = std::move(stack)});
|
||||
return v;
|
||||
}
|
||||
|
||||
auto Value::MakeBindingPlaceholderValue(std::optional<std::string> name,
|
||||
const Value* type) -> const Value* {
|
||||
auto* v = new Value();
|
||||
auto* v = global_arena->New<Value>();
|
||||
v->value = BindingPlaceholderValue({.name = std::move(name), .type = type});
|
||||
return v;
|
||||
}
|
||||
|
||||
auto Value::MakeIntType() -> const Value* {
|
||||
auto* v = new Value();
|
||||
auto* v = global_arena->New<Value>();
|
||||
v->value = IntType();
|
||||
return v;
|
||||
}
|
||||
|
||||
auto Value::MakeBoolType() -> const Value* {
|
||||
auto* v = new Value();
|
||||
auto* v = global_arena->New<Value>();
|
||||
v->value = BoolType();
|
||||
return v;
|
||||
}
|
||||
|
||||
auto Value::MakeTypeType() -> const Value* {
|
||||
auto* v = new Value();
|
||||
auto* v = global_arena->New<Value>();
|
||||
v->value = TypeType();
|
||||
return v;
|
||||
}
|
||||
|
||||
// Return a Continuation type.
|
||||
auto Value::MakeContinuationType() -> const Value* {
|
||||
auto* v = new Value();
|
||||
auto* v = global_arena->New<Value>();
|
||||
v->value = ContinuationType();
|
||||
return v;
|
||||
}
|
||||
|
||||
auto Value::MakeAutoType() -> const Value* {
|
||||
auto* v = new Value();
|
||||
auto* v = global_arena->New<Value>();
|
||||
v->value = AutoType();
|
||||
return v;
|
||||
}
|
||||
@@ -216,21 +217,21 @@ auto Value::MakeAutoType() -> const Value* {
|
||||
auto Value::MakeFunctionType(std::vector<GenericBinding> deduced_params,
|
||||
const Value* param, const Value* ret)
|
||||
-> const Value* {
|
||||
auto* v = new Value();
|
||||
auto* v = global_arena->New<Value>();
|
||||
v->value = FunctionType(
|
||||
{.deduced = std::move(deduced_params), .param = param, .ret = ret});
|
||||
return v;
|
||||
}
|
||||
|
||||
auto Value::MakePointerType(const Value* type) -> const Value* {
|
||||
auto* v = new Value();
|
||||
auto* v = global_arena->New<Value>();
|
||||
v->value = PointerType({.type = type});
|
||||
return v;
|
||||
}
|
||||
|
||||
auto Value::MakeStructType(std::string name, VarValues fields,
|
||||
VarValues methods) -> const Value* {
|
||||
auto* v = new Value();
|
||||
auto* v = global_arena->New<Value>();
|
||||
v->value = StructType({.name = std::move(name),
|
||||
.fields = std::move(fields),
|
||||
.methods = std::move(methods)});
|
||||
@@ -238,20 +239,20 @@ auto Value::MakeStructType(std::string name, VarValues fields,
|
||||
}
|
||||
|
||||
auto Value::MakeUnitTypeVal() -> const Value* {
|
||||
auto* v = new Value();
|
||||
auto* v = global_arena->New<Value>();
|
||||
v->value = TupleValue({.elements = {}});
|
||||
return v;
|
||||
}
|
||||
|
||||
auto Value::MakeChoiceType(std::string name, VarValues alts) -> const Value* {
|
||||
auto* v = new Value();
|
||||
auto* v = global_arena->New<Value>();
|
||||
v->value =
|
||||
ChoiceType({.name = std::move(name), .alternatives = std::move(alts)});
|
||||
return v;
|
||||
}
|
||||
|
||||
auto Value::MakeVariableType(std::string name) -> const Value* {
|
||||
auto* v = new Value();
|
||||
auto* v = global_arena->New<Value>();
|
||||
v->value = VariableType({.name = std::move(name)});
|
||||
return v;
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ cc_library(
|
||||
"//common:ostream",
|
||||
"//executable_semantics/ast:declaration",
|
||||
"//executable_semantics/ast:expression",
|
||||
"//executable_semantics/common:arena",
|
||||
"//executable_semantics/common:error",
|
||||
"//executable_semantics/common:tracing_flag",
|
||||
"//executable_semantics/interpreter",
|
||||
|
||||
@@ -178,10 +178,7 @@ operator and its operand, leading to three more cases:
|
||||
|
||||
{identifier} {
|
||||
BEGIN(AFTER_OPERAND);
|
||||
int n = strlen(yytext);
|
||||
auto r = reinterpret_cast<char*>(malloc((n + 1) * sizeof(char)));
|
||||
strncpy(r, yytext, n + 1);
|
||||
return yy::parser::make_identifier(r, context.current_token_position);
|
||||
return yy::parser::make_identifier(yytext, context.current_token_position);
|
||||
}
|
||||
|
||||
{integer_literal} {
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
#include "executable_semantics/ast/expression.h"
|
||||
#include "executable_semantics/ast/function_definition.h"
|
||||
#include "executable_semantics/ast/pattern.h"
|
||||
#include "executable_semantics/common/arena.h"
|
||||
#include "executable_semantics/syntax/paren_contents.h"
|
||||
|
||||
namespace Carbon {
|
||||
@@ -82,8 +83,8 @@ void yy::parser::error(const location_type&, const std::string& message) {
|
||||
} // %code
|
||||
|
||||
%token <int> integer_literal
|
||||
%token <char*> identifier
|
||||
%type <char*> designator
|
||||
%token <std::string> identifier
|
||||
%type <std::string> designator
|
||||
%type <Carbon::Declaration> declaration
|
||||
%type <Carbon::FunctionDefinition> function_declaration
|
||||
%type <Carbon::FunctionDefinition> function_definition
|
||||
@@ -310,17 +311,17 @@ pattern:
|
||||
non_expression_pattern
|
||||
{ $$ = $1; }
|
||||
| expression
|
||||
{ $$ = new Carbon::ExpressionPattern($1); }
|
||||
{ $$ = Carbon::global_arena->New<Carbon::ExpressionPattern>($1); }
|
||||
;
|
||||
non_expression_pattern:
|
||||
AUTO
|
||||
{ $$ = new Carbon::AutoPattern(yylineno); }
|
||||
{ $$ = Carbon::global_arena->New<Carbon::AutoPattern>(yylineno); }
|
||||
| binding_lhs ":" pattern
|
||||
{ $$ = new Carbon::BindingPattern(yylineno, $1, $3); }
|
||||
{ $$ = Carbon::global_arena->New<Carbon::BindingPattern>(yylineno, $1, $3); }
|
||||
| paren_pattern
|
||||
{ $$ = $1; }
|
||||
| expression tuple_pattern
|
||||
{ $$ = new Carbon::AlternativePattern(yylineno, $1, $2); }
|
||||
{ $$ = Carbon::global_arena->New<Carbon::AlternativePattern>(yylineno, $1, $2); }
|
||||
;
|
||||
binding_lhs:
|
||||
identifier { $$ = $1; }
|
||||
@@ -354,7 +355,7 @@ paren_pattern_contents:
|
||||
| paren_pattern_contents "," paren_expression_element
|
||||
{
|
||||
$$ = $1;
|
||||
$$.elements.push_back({.name = $3.name, .term = new Carbon::ExpressionPattern($3.term)});
|
||||
$$.elements.push_back({.name = $3.name, .term = Carbon::global_arena->New<Carbon::ExpressionPattern>($3.term)});
|
||||
}
|
||||
| paren_pattern_contents "," paren_pattern_element
|
||||
{
|
||||
@@ -376,24 +377,25 @@ tuple_pattern: paren_pattern_base
|
||||
// rules out the possibility of an `expression` at this point.
|
||||
maybe_empty_tuple_pattern:
|
||||
"(" ")"
|
||||
{ $$ = new Carbon::TuplePattern(yylineno, {}); }
|
||||
{ $$ = Carbon::global_arena->New<Carbon::TuplePattern>(yylineno, std::vector<Carbon::TuplePattern::Field>()); }
|
||||
| tuple_pattern
|
||||
{ $$ = $1; }
|
||||
;
|
||||
clause:
|
||||
CASE pattern DBLARROW statement
|
||||
{ $$ = new std::pair<const Carbon::Pattern*, const Carbon::Statement*>($2, $4); }
|
||||
{ $$ = Carbon::global_arena->New<std::pair<const Carbon::Pattern*, const Carbon::Statement*>>($2, $4); }
|
||||
| DEFAULT DBLARROW statement
|
||||
{
|
||||
auto vp = new Carbon::BindingPattern(
|
||||
yylineno, std::nullopt, new Carbon::AutoPattern(yylineno));
|
||||
$$ = new std::pair<const Carbon::Pattern*, const Carbon::Statement*>(vp, $3);
|
||||
auto vp = Carbon::global_arena->New<Carbon::BindingPattern>(
|
||||
yylineno, std::nullopt, Carbon::global_arena->New<Carbon::AutoPattern>(yylineno));
|
||||
$$ = Carbon::global_arena->New<std::pair<const Carbon::Pattern*, const Carbon::Statement*>>(vp, $3);
|
||||
}
|
||||
;
|
||||
clause_list:
|
||||
// Empty
|
||||
{
|
||||
$$ = new std::list<std::pair<const Carbon::Pattern*, const Carbon::Statement*>>();
|
||||
$$ = Carbon::global_arena->New<std::list<
|
||||
std::pair<const Carbon::Pattern*, const Carbon::Statement*>>>();
|
||||
}
|
||||
| clause clause_list
|
||||
{ $$ = $2; $$->push_front(*$1); }
|
||||
@@ -484,13 +486,13 @@ function_definition:
|
||||
FN identifier deduced_params maybe_empty_tuple_pattern return_type block
|
||||
{
|
||||
$$ = Carbon::FunctionDefinition(
|
||||
yylineno, $2, $3, $4, new Carbon::ExpressionPattern($5), $6);
|
||||
yylineno, $2, $3, $4, Carbon::global_arena->New<Carbon::ExpressionPattern>($5), $6);
|
||||
}
|
||||
| FN identifier deduced_params maybe_empty_tuple_pattern DBLARROW expression ";"
|
||||
{
|
||||
$$ = Carbon::FunctionDefinition(
|
||||
yylineno, $2, $3, $4,
|
||||
new Carbon::AutoPattern(yylineno),
|
||||
Carbon::global_arena->New<Carbon::AutoPattern>(yylineno),
|
||||
Carbon::Statement::MakeReturn(yylineno, $6));
|
||||
}
|
||||
;
|
||||
@@ -498,10 +500,10 @@ function_declaration:
|
||||
FN identifier deduced_params maybe_empty_tuple_pattern return_type ";"
|
||||
{
|
||||
$$ = Carbon::FunctionDefinition(
|
||||
yylineno, $2, $3, $4, new Carbon::ExpressionPattern($5), 0); }
|
||||
yylineno, $2, $3, $4, Carbon::global_arena->New<Carbon::ExpressionPattern>($5), 0); }
|
||||
;
|
||||
variable_declaration: identifier ":" pattern
|
||||
{ $$ = new Carbon::BindingPattern(yylineno, $1, $3); }
|
||||
{ $$ = Carbon::global_arena->New<Carbon::BindingPattern>(yylineno, $1, $3); }
|
||||
;
|
||||
member: VAR variable_declaration ";"
|
||||
{ $$ = Carbon::Member::MakeFieldMember(yylineno, $2); }
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "executable_semantics/syntax/syntax_helpers.h"
|
||||
|
||||
#include "common/ostream.h"
|
||||
#include "executable_semantics/common/arena.h"
|
||||
#include "executable_semantics/common/tracing_flag.h"
|
||||
#include "executable_semantics/interpreter/interpreter.h"
|
||||
#include "executable_semantics/interpreter/typecheck.h"
|
||||
@@ -19,7 +20,7 @@ void ExecProgram(std::list<Declaration>* fs) {
|
||||
}
|
||||
llvm::outs() << "********** type checking **********\n";
|
||||
}
|
||||
state = new State(); // Compile-time state.
|
||||
state = global_arena->New<State>(); // Compile-time state.
|
||||
TypeCheckContext p = TopLevel(fs);
|
||||
TypeEnv top = p.types;
|
||||
Env ct_top = p.values;
|
||||
|
||||
@@ -111,9 +111,6 @@ def _update_list(use_git_state):
|
||||
|
||||
def _update_golden(test):
|
||||
"""Updates the golden file for `test` by running executable_semantics."""
|
||||
# TODO(#580): Remove this when leaks are fixed.
|
||||
env = os.environ.copy()
|
||||
env["ASAN_OPTIONS"] = "detect_leaks=0"
|
||||
# Invoke the test update directly in order to allow parallel execution
|
||||
# (`bazel run` will serialize).
|
||||
p = subprocess.run(
|
||||
@@ -123,7 +120,6 @@ def _update_golden(test):
|
||||
"%s/executable_semantics %s/%s.carbon" % (_BINDIR, _TESTDATA, test),
|
||||
"--update",
|
||||
],
|
||||
env=env,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user