Skip to content

Commit

Permalink
[Sema] reduce the amound of places where the tree-walk interpreter is…
Browse files Browse the repository at this point in the history
… run
  • Loading branch information
isuckatcs committed Jul 13, 2024
1 parent 1ced406 commit e34bf6c
Show file tree
Hide file tree
Showing 13 changed files with 241 additions and 503 deletions.
61 changes: 33 additions & 28 deletions src/sema.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -270,8 +270,7 @@ std::unique_ptr<ResolvedCallExpr> Sema::resolveCallExpr(const CallExpr &call) {
if (resolvedArg->type.kind != resolvedFunctionDecl->params[idx]->type.kind)
return report(resolvedArg->location, "unexpected type of argument");

if (std::optional<double> val = cee.evaluate(*resolvedArg))
resolvedArg->setConstantValue(val);
resolvedArg->setConstantValue(cee.evaluate(*resolvedArg));

++idx;
resolvedArguments.emplace_back(std::move(resolvedArg));
Expand Down Expand Up @@ -318,6 +317,8 @@ std::unique_ptr<ResolvedIfStmt> Sema::resolveIfStmt(const IfStmt &ifStmt) {
return nullptr;
}

condition->setConstantValue(cee.evaluate(*condition));

return std::make_unique<ResolvedIfStmt>(ifStmt.location, std::move(condition),
std::move(trueBlock),
std::move(resolvedFalseBlock));
Expand All @@ -332,6 +333,8 @@ Sema::resolveWhileStmt(const WhileStmt &whileStmt) {

varOrReturn(body, resolveBlock(*whileStmt.body));

condition->setConstantValue(cee.evaluate(*condition));

return std::make_unique<ResolvedWhileStmt>(
whileStmt.location, std::move(condition), std::move(body));
}
Expand Down Expand Up @@ -366,6 +369,8 @@ Sema::resolveAssignment(const Assignment &assignment) {
return report(resolvedRHS->location,
"assigned value type doesn't match variable type");

resolvedRHS->setConstantValue(cee.evaluate(*resolvedRHS));

return std::make_unique<ResolvedAssignment>(
assignment.location, std::move(resolvedLHS), std::move(resolvedRHS));
}
Expand All @@ -389,6 +394,8 @@ Sema::resolveReturnStmt(const ReturnStmt &returnStmt) {

if (currentFunction->type.kind != resolvedExpr->type.kind)
return report(resolvedExpr->location, "unexpected return type");

resolvedExpr->setConstantValue(cee.evaluate(*resolvedExpr));
}

return std::make_unique<ResolvedReturnStmt>(returnStmt.location,
Expand All @@ -397,33 +404,27 @@ Sema::resolveReturnStmt(const ReturnStmt &returnStmt) {

std::unique_ptr<ResolvedExpr> Sema::resolveExpr(const Expr &expr) {

std::unique_ptr<ResolvedExpr> resolvedExpr = nullptr;

if (const auto *numberLiteral = dynamic_cast<const NumberLiteral *>(&expr))
resolvedExpr = std::make_unique<ResolvedNumberLiteral>(
numberLiteral->location, std::stod(numberLiteral->value));
else if (const auto *declRefExpr = dynamic_cast<const DeclRefExpr *>(&expr))
resolvedExpr = resolveDeclRefExpr(*declRefExpr);
else if (const auto *callExpr = dynamic_cast<const CallExpr *>(&expr))
resolvedExpr = resolveCallExpr(*callExpr);
else if (const auto *groupingExpr = dynamic_cast<const GroupingExpr *>(&expr))
resolvedExpr = resolveGroupingExpr(*groupingExpr);
else if (const auto *binaryOperator =
dynamic_cast<const BinaryOperator *>(&expr))
resolvedExpr = resolveBinaryOperator(*binaryOperator);
else {
const auto *unaryOperator = dynamic_cast<const UnaryOperator *>(&expr);
assert(unaryOperator && "unexpected expression");
resolvedExpr = resolveUnaryOperator(*unaryOperator);
}
if (const auto *number = dynamic_cast<const NumberLiteral *>(&expr))
return std::make_unique<ResolvedNumberLiteral>(number->location,
std::stod(number->value));

if (!resolvedExpr)
return nullptr;
if (const auto *declRefExpr = dynamic_cast<const DeclRefExpr *>(&expr))
return resolveDeclRefExpr(*declRefExpr);

if (std::optional<double> val = cee.evaluate(*resolvedExpr))
resolvedExpr->setConstantValue(val);
if (const auto *callExpr = dynamic_cast<const CallExpr *>(&expr))
return resolveCallExpr(*callExpr);

return resolvedExpr;
if (const auto *groupingExpr = dynamic_cast<const GroupingExpr *>(&expr))
return resolveGroupingExpr(*groupingExpr);

if (const auto *binaryOperator = dynamic_cast<const BinaryOperator *>(&expr))
return resolveBinaryOperator(*binaryOperator);

if (const auto *unaryOperator = dynamic_cast<const UnaryOperator *>(&expr))
return resolveUnaryOperator(*unaryOperator);

assert(false && "unexpected expression");
return nullptr;
}

std::unique_ptr<ResolvedBlock> Sema::resolveBlock(const Block &block) {
Expand Down Expand Up @@ -490,8 +491,12 @@ std::unique_ptr<ResolvedVarDecl> Sema::resolveVarDecl(const VarDecl &varDecl) {
"' has invalid '" +
resolvableType.name + "' type");

if (resolvedInitializer && resolvedInitializer->type.kind != type->kind)
return report(resolvedInitializer->location, "initializer type mismatch");
if (resolvedInitializer) {
if (resolvedInitializer->type.kind != type->kind)
return report(resolvedInitializer->location, "initializer type mismatch");

resolvedInitializer->setConstantValue(cee.evaluate(*resolvedInitializer));
}

return std::make_unique<ResolvedVarDecl>(varDecl.location, varDecl.identifier,
*type, varDecl.isMutable,
Expand Down
38 changes: 13 additions & 25 deletions test/cfg/arguments.yl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: compiler %s -cfg-dump 2>&1 | filecheck %s
// RUN: compiler %s -cfg-dump 2>&1 | filecheck %s --match-full-lines
fn foo(x: number, y: number): void{}

fn main(): void {
Expand All @@ -12,39 +12,27 @@ fn main(): void {
// CHECK-NEXT: [1]
// CHECK-NEXT: preds: 2
// CHECK-NEXT: succs: 0
// CHECK-NEXT: NumberLiteral: '1'
// CHECK-NEXT: | value: 1
// CHECK-NEXT: NumberLiteral: '2'
// CHECK-NEXT: | value: 2
// CHECK-NEXT: ResolvedNumberLiteral: '1'
// CHECK-NEXT: ResolvedNumberLiteral: '2'
// CHECK-NEXT: ResolvedBinaryOperator: '+'
// CHECK-NEXT: | value: 3
// CHECK-NEXT: NumberLiteral: '1'
// CHECK-NEXT: | value: 1
// CHECK-NEXT: NumberLiteral: '2'
// CHECK-NEXT: | value: 2
// CHECK-NEXT: NumberLiteral: '3'
// CHECK-NEXT: | value: 3
// CHECK-NEXT: NumberLiteral: '4'
// CHECK-NEXT: | value: 4
// CHECK-NEXT: ResolvedNumberLiteral: '1'
// CHECK-NEXT: ResolvedNumberLiteral: '2'
// CHECK-NEXT: ResolvedNumberLiteral: '3'
// CHECK-NEXT: ResolvedNumberLiteral: '4'
// CHECK-NEXT: ResolvedBinaryOperator: '+'
// CHECK-NEXT: | value: 7
// CHECK-NEXT: NumberLiteral: '3'
// CHECK-NEXT: | value: 3
// CHECK-NEXT: NumberLiteral: '4'
// CHECK-NEXT: | value: 4
// CHECK-NEXT: ResolvedNumberLiteral: '3'
// CHECK-NEXT: ResolvedNumberLiteral: '4'
// CHECK-NEXT: ResolvedCallExpr: @({{.*}}) foo
// CHECK-NEXT: ResolvedBinaryOperator: '+'
// CHECK-NEXT: | value: 3
// CHECK-NEXT: NumberLiteral: '1'
// CHECK-NEXT: | value: 1
// CHECK-NEXT: NumberLiteral: '2'
// CHECK-NEXT: | value: 2
// CHECK-NEXT: ResolvedNumberLiteral: '1'
// CHECK-NEXT: ResolvedNumberLiteral: '2'
// CHECK-NEXT: ResolvedBinaryOperator: '+'
// CHECK-NEXT: | value: 7
// CHECK-NEXT: NumberLiteral: '3'
// CHECK-NEXT: | value: 3
// CHECK-NEXT: NumberLiteral: '4'
// CHECK-NEXT: | value: 4
// CHECK-NEXT: ResolvedNumberLiteral: '3'
// CHECK-NEXT: ResolvedNumberLiteral: '4'
// CHECK-NEXT:
// CHECK-NEXT: [0 (exit)]
// CHECK-NEXT: preds: 1
Expand Down
19 changes: 8 additions & 11 deletions test/cfg/assignment.yl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: compiler %s -cfg-dump 2>&1 | filecheck %s
// RUN: compiler %s -cfg-dump 2>&1 | filecheck %s --match-full-lines
fn main(): void {
var x: number;

Expand All @@ -18,31 +18,28 @@ fn main(): void {
// CHECK-NEXT: succs: 0
// CHECK-NEXT: ResolvedDeclStmt:
// CHECK-NEXT: ResolvedVarDecl: @({{.*}}) x:
// CHECK-NEXT: NumberLiteral: '2'
// CHECK-NEXT: ResolvedNumberLiteral: '2'
// CHECK-NEXT: | value: 2
// CHECK-NEXT: ResolvedAssignment:
// CHECK-NEXT: ResolvedDeclRefExpr: @({{.*}}) x
// CHECK-NEXT: NumberLiteral: '2'
// CHECK-NEXT: ResolvedNumberLiteral: '2'
// CHECK-NEXT: | value: 2
// CHECK-NEXT: NumberLiteral: '3'
// CHECK-NEXT: ResolvedNumberLiteral: '3'
// CHECK-NEXT: | value: 3
// CHECK-NEXT: ResolvedAssignment:
// CHECK-NEXT: ResolvedDeclRefExpr: @({{.*}}) x
// CHECK-NEXT: NumberLiteral: '3'
// CHECK-NEXT: ResolvedNumberLiteral: '3'
// CHECK-NEXT: | value: 3
// CHECK-NEXT: ResolvedDeclRefExpr: @({{.*}}) x
// CHECK-NEXT: NumberLiteral: '1'
// CHECK-NEXT: | value: 1
// CHECK-NEXT: ResolvedNumberLiteral: '1'
// CHECK-NEXT: ResolvedBinaryOperator: '+'
// CHECK-NEXT: ResolvedDeclRefExpr: @({{.*}}) x
// CHECK-NEXT: NumberLiteral: '1'
// CHECK-NEXT: | value: 1
// CHECK-NEXT: ResolvedNumberLiteral: '1'
// CHECK-NEXT: ResolvedAssignment:
// CHECK-NEXT: ResolvedDeclRefExpr: @({{.*}}) x
// CHECK-NEXT: ResolvedBinaryOperator: '+'
// CHECK-NEXT: ResolvedDeclRefExpr: @({{.*}}) x
// CHECK-NEXT: NumberLiteral: '1'
// CHECK-NEXT: | value: 1
// CHECK-NEXT: ResolvedNumberLiteral: '1'
// CHECK-NEXT:
// CHECK-NEXT: [0 (exit)]
// CHECK-NEXT: preds: 1
Expand Down
62 changes: 1 addition & 61 deletions test/cfg/condition.yl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: compiler %s -cfg-dump 2>&1 | filecheck %s
// RUN: compiler %s -cfg-dump 2>&1 | filecheck %s --match-full-lines
fn main(): void {
3.0 || 2.0;
1.0;
Expand All @@ -12,17 +12,11 @@ fn main(): void {
// CHECK-NEXT: preds: 2
// CHECK-NEXT: succs: 0
// CHECK-NEXT: ResolvedNumberLiteral: '3'
// CHECK-NEXT: | value: 3
// CHECK-NEXT: ResolvedNumberLiteral: '2'
// CHECK-NEXT: | value: 2
// CHECK-NEXT: ResolvedBinaryOperator: '||'
// CHECK-NEXT: | value: 1
// CHECK-NEXT: ResolvedNumberLiteral: '3'
// CHECK-NEXT: | value: 3
// CHECK-NEXT: ResolvedNumberLiteral: '2'
// CHECK-NEXT: | value: 2
// CHECK-NEXT: ResolvedNumberLiteral: '1'
// CHECK-NEXT: | value: 1
// CHECK-NEXT:
// CHECK-NEXT: [0 (exit)]
// CHECK-NEXT: preds: 1
Expand All @@ -41,17 +35,11 @@ fn and(): void {
// CHECK-NEXT: preds: 2
// CHECK-NEXT: succs: 0
// CHECK-NEXT: ResolvedNumberLiteral: '3'
// CHECK-NEXT: | value: 3
// CHECK-NEXT: ResolvedNumberLiteral: '2'
// CHECK-NEXT: | value: 2
// CHECK-NEXT: ResolvedBinaryOperator: '&&'
// CHECK-NEXT: | value: 1
// CHECK-NEXT: ResolvedNumberLiteral: '3'
// CHECK-NEXT: | value: 3
// CHECK-NEXT: ResolvedNumberLiteral: '2'
// CHECK-NEXT: | value: 2
// CHECK-NEXT: ResolvedNumberLiteral: '1'
// CHECK-NEXT: | value: 1
// CHECK-NEXT:
// CHECK-NEXT: [0 (exit)]
// CHECK-NEXT: preds: 1
Expand All @@ -70,29 +58,17 @@ fn multipleOr(): void {
// CHECK-NEXT: preds: 2
// CHECK-NEXT: succs: 0
// CHECK-NEXT: ResolvedNumberLiteral: '4'
// CHECK-NEXT: | value: 4
// CHECK-NEXT: ResolvedNumberLiteral: '3'
// CHECK-NEXT: | value: 3
// CHECK-NEXT: ResolvedBinaryOperator: '||'
// CHECK-NEXT: | value: 1
// CHECK-NEXT: ResolvedNumberLiteral: '4'
// CHECK-NEXT: | value: 4
// CHECK-NEXT: ResolvedNumberLiteral: '3'
// CHECK-NEXT: | value: 3
// CHECK-NEXT: ResolvedNumberLiteral: '2'
// CHECK-NEXT: | value: 2
// CHECK-NEXT: ResolvedBinaryOperator: '||'
// CHECK-NEXT: | value: 1
// CHECK-NEXT: ResolvedBinaryOperator: '||'
// CHECK-NEXT: | value: 1
// CHECK-NEXT: ResolvedNumberLiteral: '4'
// CHECK-NEXT: | value: 4
// CHECK-NEXT: ResolvedNumberLiteral: '3'
// CHECK-NEXT: | value: 3
// CHECK-NEXT: ResolvedNumberLiteral: '2'
// CHECK-NEXT: | value: 2
// CHECK-NEXT: ResolvedNumberLiteral: '1'
// CHECK-NEXT: | value: 1
// CHECK-NEXT:
// CHECK-NEXT: [0 (exit)]
// CHECK-NEXT: preds: 1
Expand All @@ -111,29 +87,17 @@ fn multipleAnd(): void {
// CHECK-NEXT: preds: 2
// CHECK-NEXT: succs: 0
// CHECK-NEXT: ResolvedNumberLiteral: '4'
// CHECK-NEXT: | value: 4
// CHECK-NEXT: ResolvedNumberLiteral: '3'
// CHECK-NEXT: | value: 3
// CHECK-NEXT: ResolvedBinaryOperator: '&&'
// CHECK-NEXT: | value: 1
// CHECK-NEXT: ResolvedNumberLiteral: '4'
// CHECK-NEXT: | value: 4
// CHECK-NEXT: ResolvedNumberLiteral: '3'
// CHECK-NEXT: | value: 3
// CHECK-NEXT: ResolvedNumberLiteral: '2'
// CHECK-NEXT: | value: 2
// CHECK-NEXT: ResolvedBinaryOperator: '&&'
// CHECK-NEXT: | value: 1
// CHECK-NEXT: ResolvedBinaryOperator: '&&'
// CHECK-NEXT: | value: 1
// CHECK-NEXT: ResolvedNumberLiteral: '4'
// CHECK-NEXT: | value: 4
// CHECK-NEXT: ResolvedNumberLiteral: '3'
// CHECK-NEXT: | value: 3
// CHECK-NEXT: ResolvedNumberLiteral: '2'
// CHECK-NEXT: | value: 2
// CHECK-NEXT: ResolvedNumberLiteral: '1'
// CHECK-NEXT: | value: 1
// CHECK-NEXT:
// CHECK-NEXT: [0 (exit)]
// CHECK-NEXT: preds: 1
Expand All @@ -152,29 +116,17 @@ fn andOr(): void {
// CHECK-NEXT: preds: 2
// CHECK-NEXT: succs: 0
// CHECK-NEXT: ResolvedNumberLiteral: '4'
// CHECK-NEXT: | value: 4
// CHECK-NEXT: ResolvedNumberLiteral: '3'
// CHECK-NEXT: | value: 3
// CHECK-NEXT: ResolvedBinaryOperator: '&&'
// CHECK-NEXT: | value: 1
// CHECK-NEXT: ResolvedNumberLiteral: '4'
// CHECK-NEXT: | value: 4
// CHECK-NEXT: ResolvedNumberLiteral: '3'
// CHECK-NEXT: | value: 3
// CHECK-NEXT: ResolvedNumberLiteral: '2'
// CHECK-NEXT: | value: 2
// CHECK-NEXT: ResolvedBinaryOperator: '||'
// CHECK-NEXT: | value: 1
// CHECK-NEXT: ResolvedBinaryOperator: '&&'
// CHECK-NEXT: | value: 1
// CHECK-NEXT: ResolvedNumberLiteral: '4'
// CHECK-NEXT: | value: 4
// CHECK-NEXT: ResolvedNumberLiteral: '3'
// CHECK-NEXT: | value: 3
// CHECK-NEXT: ResolvedNumberLiteral: '2'
// CHECK-NEXT: | value: 2
// CHECK-NEXT: ResolvedNumberLiteral: '1'
// CHECK-NEXT: | value: 1
// CHECK-NEXT:
// CHECK-NEXT: [0 (exit)]
// CHECK-NEXT: preds: 1
Expand All @@ -193,29 +145,17 @@ fn orAnd(): void {
// CHECK-NEXT: preds: 2
// CHECK-NEXT: succs: 0
// CHECK-NEXT: ResolvedNumberLiteral: '4'
// CHECK-NEXT: | value: 4
// CHECK-NEXT: ResolvedNumberLiteral: '3'
// CHECK-NEXT: | value: 3
// CHECK-NEXT: ResolvedNumberLiteral: '2'
// CHECK-NEXT: | value: 2
// CHECK-NEXT: ResolvedBinaryOperator: '&&'
// CHECK-NEXT: | value: 1
// CHECK-NEXT: ResolvedNumberLiteral: '3'
// CHECK-NEXT: | value: 3
// CHECK-NEXT: ResolvedNumberLiteral: '2'
// CHECK-NEXT: | value: 2
// CHECK-NEXT: ResolvedBinaryOperator: '||'
// CHECK-NEXT: | value: 1
// CHECK-NEXT: ResolvedNumberLiteral: '4'
// CHECK-NEXT: | value: 4
// CHECK-NEXT: ResolvedBinaryOperator: '&&'
// CHECK-NEXT: | value: 1
// CHECK-NEXT: ResolvedNumberLiteral: '3'
// CHECK-NEXT: | value: 3
// CHECK-NEXT: ResolvedNumberLiteral: '2'
// CHECK-NEXT: | value: 2
// CHECK-NEXT: ResolvedNumberLiteral: '1'
// CHECK-NEXT: | value: 1
// CHECK-NEXT:
// CHECK-NEXT: [0 (exit)]
// CHECK-NEXT: preds: 1
Expand Down
Loading

0 comments on commit e34bf6c

Please sign in to comment.