add C style for loop
This commit is contained in:
parent
1c4022cebc
commit
ddd7fb0467
|
@ -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 {};
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue