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++;
|
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 {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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';
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue