add C style for loop

This commit is contained in:
Thomas Lindner 2023-01-07 17:10:03 +01:00
parent 1c4022cebc
commit ddd7fb0467
5 changed files with 64 additions and 33 deletions

View file

@ -56,43 +56,65 @@ std::any EmitVisitor::visitStatement(xlangParser::StatementContext *ctx) {
int block = blockcount++; int block = blockcount++;
loopstack.push_back(block); loopstack.push_back(block);
output << "@while" << block << "_expr" << std::endl; output << "@loop" << block << "_continue" << std::endl;
output << "@loop" << block << "_expr" << std::endl;
tmpcount = 0; tmpcount = 0;
visitCondition(ctx->condition()); visitCondition(ctx->condition());
output << " jnz " << last << ", @while" << block << "_body, @while" output << " jnz " << last << ", @loop" << block << "_body, @loop" << block
<< block << "_end" << std::endl; << "_end" << std::endl;
output << "@while" << block << "_body" << std::endl; output << "@loop" << block << "_body" << std::endl;
visitBlock(ctx->block(0)); visitBlock(ctx->block(0));
output << " jmp @while" << block << "_expr" << std::endl; output << " jmp @loop" << block << "_expr" << std::endl;
output << "@while" << block << "_end" << std::endl; output << "@loop" << block << "_end" << std::endl;
loopstack.pop_back();
return {};
}
if (ctx->For()) {
int block = blockcount++;
loopstack.push_back(block);
tmpcount = 0;
visitValue(ctx->value(0));
output << "@loop" << block << "_expr" << std::endl;
tmpcount = 0;
visitCondition(ctx->condition());
output << " jnz " << last << ", @loop" << block << "_body, @loop" << block
<< "_end" << std::endl;
output << "@loop" << block << "_body" << std::endl;
visitBlock(ctx->block(0));
output << "@loop" << block << "_continue" << std::endl;
tmpcount = 0;
visitValue(ctx->value(1));
output << " jmp @loop" << block << "_expr" << std::endl;
output << "@loop" << block << "_end" << std::endl;
loopstack.pop_back(); loopstack.pop_back();
return {}; return {};
} }
if (ctx->Break()) { if (ctx->Break()) {
output << " jmp @while" << loopstack.back() << "_end" << std::endl; output << " jmp @loop" << loopstack.back() << "_end" << std::endl;
output << "@dead" << blockcount++ << std::endl; output << "@dead" << blockcount++ << std::endl;
return {}; return {};
} }
if (ctx->Continue()) { if (ctx->Continue()) {
output << " jmp @while" << loopstack.back() << "_expr" << std::endl; output << " jmp @loop" << loopstack.back() << "_expr" << std::endl;
output << "@dead" << blockcount++ << std::endl; output << "@dead" << blockcount++ << std::endl;
return {}; return {};
} }
if (ctx->Return()) { if (ctx->Return()) {
tmpcount = 0; tmpcount = 0;
visitValue(ctx->value()); visitValue(ctx->value(0));
output << " ret " << last << std::endl; output << " ret " << last << std::endl;
output << "@dead" << blockcount++ << std::endl; output << "@dead" << blockcount++ << std::endl;
return {}; return {};
} }
if (ctx->Print()) { if (ctx->Print()) {
tmpcount = 0; tmpcount = 0;
visitValue(ctx->value()); visitValue(ctx->value(0));
output << " call $printf(l $printformat, ..., w " << last << ")" output << " call $printf(l $printformat, ..., w " << last << ")"
<< std::endl; << std::endl;
return {}; return {};
} }
visitValue(ctx->value()); visitValue(ctx->value(0));
return {}; return {};
} }

View file

@ -75,22 +75,37 @@ std::any TypeCheckVisitor::visitBlock(xlangParser::BlockContext *ctx) {
} }
std::any TypeCheckVisitor::visitStatement(xlangParser::StatementContext *ctx) { std::any TypeCheckVisitor::visitStatement(xlangParser::StatementContext *ctx) {
if (auto condition = ctx->condition()) { if (ctx->If()) {
scope.enter();
auto condition = ctx->condition();
auto type = std::any_cast<Type>(visitCondition(condition)); auto type = std::any_cast<Type>(visitCondition(condition));
if (type != Type::Boolean) { if (type != Type::Boolean) {
errorlistener.typeMismatch(condition->getStart(), Type::Boolean, type); errorlistener.typeMismatch(condition->getStart(), Type::Boolean, type);
} }
if (ctx->While()) {
loopcount++;
}
visitBlock(ctx->block(0)); visitBlock(ctx->block(0));
if (ctx->While()) {
loopcount--;
}
if (ctx->Else()) { if (ctx->Else()) {
visitBlock(ctx->block(1)); visitBlock(ctx->block(1));
} }
scope.leave();
return {};
}
if (ctx->While() || ctx->For()) {
scope.enter();
if (ctx->For()) {
visitValue(ctx->value(0));
}
auto condition = ctx->condition();
auto type = std::any_cast<Type>(visitCondition(condition));
if (type != Type::Boolean) {
errorlistener.typeMismatch(condition->getStart(), Type::Boolean, type);
}
if (ctx->For()) {
visitValue(ctx->value(1));
}
loopcount++;
visitBlock(ctx->block(0));
loopcount--;
scope.leave();
return {}; return {};
} }
if (ctx->Break()) { if (ctx->Break()) {
@ -106,10 +121,10 @@ std::any TypeCheckVisitor::visitStatement(xlangParser::StatementContext *ctx) {
return {}; return {};
} }
if (ctx->Return()) { if (ctx->Return()) {
auto type = std::any_cast<Type>(visitValue(ctx->value())); auto type = std::any_cast<Type>(visitValue(ctx->value(0)));
if (type != returntype) { if (type != returntype) {
errorlistener.typeMismatch(ctx->value()->getStart(), returntype, type); errorlistener.typeMismatch(ctx->value(0)->getStart(), returntype, type);
} }
} }
visitChildren(ctx); visitChildren(ctx);

View file

@ -9,6 +9,7 @@ type : TypeInteger
block : LeftBrace statement* RightBrace; block : LeftBrace statement* RightBrace;
statement : If condition block (Else block)? statement : If condition block (Else block)?
| While condition block | While condition block
| For value Semicolon condition Semicolon value block
| Break Semicolon | Break Semicolon
| Continue Semicolon | Continue Semicolon
| Return value Semicolon | Return value Semicolon
@ -54,6 +55,7 @@ TypeBoolean : 'bool';
If : 'if'; If : 'if';
Else : 'else'; Else : 'else';
While : 'while'; While : 'while';
For : 'for';
Break : 'break'; Break : 'break';
Continue : 'continue'; Continue : 'continue';
Return : 'return'; Return : 'return';

View file

@ -1,9 +1,7 @@
main() : int { main() : int {
i := 0; for i := 0; i < 10; i =+ 1 {
while i < 10 {
print fib_rec(i); print fib_rec(i);
print fib_iter(i); print fib_iter(i);
i =+ 1;
} }
} }
@ -17,12 +15,10 @@ fib_rec(n : int) : int {
fib_iter(n : int) : int { fib_iter(n : int) : int {
x0 := 1; x0 := 1;
x1 := 1; x1 := 1;
i := 0; for i := 0; i < n; i =+ 1 {
while i < n {
t := x0 + x1; t := x0 + x1;
x0 = x1; x0 = x1;
x1 = t; x1 = t;
i =+ 1;
} }
return x0; return x0;
} }

View file

@ -1,19 +1,15 @@
main() : int { main() : int {
print 2; print 2;
i := 3; for i := 3; i < 100; i =+ 2 {
while i < 100 {
composite := false; composite := false;
j := 3; for j := 3; j < i; j =+ 2 {
while j < i {
if i % j == 0 { if i % j == 0 {
composite = true; composite = true;
break; break;
} }
j =+ 2;
} }
if not composite { if not composite {
print i; print i;
} }
i =+ 2;
} }
} }