add C style for loop

development
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++;
loopstack.push_back(block);
output << "@while" << block << "_expr" << std::endl;
output << "@loop" << block << "_continue" << std::endl;
output << "@loop" << block << "_expr" << std::endl;
tmpcount = 0;
visitCondition(ctx->condition());
output << " jnz " << last << ", @while" << block << "_body, @while"
<< block << "_end" << std::endl;
output << "@while" << block << "_body" << std::endl;
output << " jnz " << last << ", @loop" << block << "_body, @loop" << block
<< "_end" << std::endl;
output << "@loop" << block << "_body" << std::endl;
visitBlock(ctx->block(0));
output << " jmp @while" << block << "_expr" << std::endl;
output << "@while" << block << "_end" << std::endl;
output << " jmp @loop" << block << "_expr" << 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();
return {};
}
if (ctx->Break()) {
output << " jmp @while" << loopstack.back() << "_end" << std::endl;
output << " jmp @loop" << loopstack.back() << "_end" << std::endl;
output << "@dead" << blockcount++ << std::endl;
return {};
}
if (ctx->Continue()) {
output << " jmp @while" << loopstack.back() << "_expr" << std::endl;
output << " jmp @loop" << loopstack.back() << "_expr" << std::endl;
output << "@dead" << blockcount++ << std::endl;
return {};
}
if (ctx->Return()) {
tmpcount = 0;
visitValue(ctx->value());
visitValue(ctx->value(0));
output << " ret " << last << std::endl;
output << "@dead" << blockcount++ << std::endl;
return {};
}
if (ctx->Print()) {
tmpcount = 0;
visitValue(ctx->value());
visitValue(ctx->value(0));
output << " call $printf(l $printformat, ..., w " << last << ")"
<< std::endl;
return {};
}
visitValue(ctx->value());
visitValue(ctx->value(0));
return {};
}

View File

@ -75,22 +75,37 @@ std::any TypeCheckVisitor::visitBlock(xlangParser::BlockContext *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));
if (type != Type::Boolean) {
errorlistener.typeMismatch(condition->getStart(), Type::Boolean, type);
}
if (ctx->While()) {
loopcount++;
}
visitBlock(ctx->block(0));
if (ctx->While()) {
loopcount--;
}
if (ctx->Else()) {
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 {};
}
if (ctx->Break()) {
@ -106,10 +121,10 @@ std::any TypeCheckVisitor::visitStatement(xlangParser::StatementContext *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) {
errorlistener.typeMismatch(ctx->value()->getStart(), returntype, type);
errorlistener.typeMismatch(ctx->value(0)->getStart(), returntype, type);
}
}
visitChildren(ctx);

View File

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

View File

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

View File

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