|
@@ -893,10 +893,15 @@ export class IVProgParser {
|
|
this.pushScope(IVProgParser.BREAKABLE);
|
|
this.pushScope(IVProgParser.BREAKABLE);
|
|
const for_token = this.getToken();
|
|
const for_token = this.getToken();
|
|
this.pos += 1;
|
|
this.pos += 1;
|
|
- const for_id = this.parseID();
|
|
|
|
- const for_from = this.parseForFrom();
|
|
|
|
- const for_to = this.parseForTo();
|
|
|
|
- let maybePass = this.parseForPass();
|
|
|
|
|
|
+ // parse ID
|
|
|
|
+ const id_token = this.getToken();
|
|
|
|
+ const id = this.parseID();
|
|
|
|
+ const for_id = new Expressions.VariableLiteral(id);
|
|
|
|
+ for_id.sourceInfo = SourceInfo.createSourceInfo(id_token);
|
|
|
|
+ // END parse ID
|
|
|
|
+ const for_from = this.parseForParameters(this.lexerClass.RK_FOR_FROM);
|
|
|
|
+ const for_to = this.parseForParameters(this.lexerClass.RK_FOR_TO);
|
|
|
|
+ let maybePass = this.parseForParameters(this.lexerClass.RK_FOR_PASS);
|
|
this.consumeNewLines();
|
|
this.consumeNewLines();
|
|
const commandsBlock = this.parseCommandBlock();
|
|
const commandsBlock = this.parseCommandBlock();
|
|
this.popScope();
|
|
this.popScope();
|
|
@@ -996,71 +1001,45 @@ export class IVProgParser {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- parseForFrom () {
|
|
|
|
- const from_token = this.getToken();
|
|
|
|
- if (from_token.type !== this.lexerClass.RK_FOR_FROM) {
|
|
|
|
- // TODO better error message
|
|
|
|
- const keyword = this.lexer.literalNames[this.lexerClass.RK_FOR_FROM];
|
|
|
|
- throw new Error("Error de sintaxe no comando repita_para: esperava-se "+keyword+" mas encontrou "+from_token.text);
|
|
|
|
- }
|
|
|
|
- this.pos += 1;
|
|
|
|
- const int_or_id = this.getToken();
|
|
|
|
- if (int_or_id.type === this.lexerClass.ID) {
|
|
|
|
- return this.parseID();
|
|
|
|
- } else if (int_or_id.type === this.lexerClass.INTEGER) {
|
|
|
|
- this.pos += 1;
|
|
|
|
- return this.getIntLiteral(int_or_id);
|
|
|
|
- } else {
|
|
|
|
- // TODO better error message
|
|
|
|
- const keyword = this.lexer.literalNames[this.lexerClass.RK_FOR_FROM];
|
|
|
|
- throw new Error("Error de sintaxe no comando repeita_para: "+ int_or_id.text + " não é compativel com o esperado para o paramentro "+ keyword + ". O valor deve ser um inteiro ou variável.");
|
|
|
|
|
|
+ parseForParameters (keyword_code) {
|
|
|
|
+ if(keyword_code === this.lexerClass.RK_FOR_PASS) {
|
|
|
|
+ if(this.checkOpenCurly(true)) {
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- }
|
|
|
|
-
|
|
|
|
- parseForTo () {
|
|
|
|
const from_token = this.getToken();
|
|
const from_token = this.getToken();
|
|
- if (from_token.type !== this.lexerClass.RK_FOR_TO) {
|
|
|
|
|
|
+ if (from_token.type !== keyword_code) {
|
|
// TODO better error message
|
|
// TODO better error message
|
|
- const keyword = this.lexer.literalNames[this.lexerClass.RK_FOR_TO];
|
|
|
|
|
|
+ const keyword = this.lexer.literalNames[keyword_code];
|
|
throw new Error("Error de sintaxe no comando repita_para: esperava-se "+keyword+" mas encontrou "+from_token.text);
|
|
throw new Error("Error de sintaxe no comando repita_para: esperava-se "+keyword+" mas encontrou "+from_token.text);
|
|
}
|
|
}
|
|
this.pos += 1;
|
|
this.pos += 1;
|
|
- const int_or_id = this.getToken();
|
|
|
|
- if (int_or_id.type === this.lexerClass.ID) {
|
|
|
|
- return this.parseID();
|
|
|
|
- } else if (int_or_id.type === this.lexerClass.INTEGER) {
|
|
|
|
|
|
+ let int_or_id = this.getToken();
|
|
|
|
+ let is_unary_op = false;
|
|
|
|
+ let op = null;
|
|
|
|
+ if(int_or_id.type === this.lexerClass.SUM_OP) {
|
|
|
|
+ is_unary_op = true;
|
|
|
|
+ op = int_or_id.text;
|
|
this.pos += 1;
|
|
this.pos += 1;
|
|
- return this.getIntLiteral(int_or_id);
|
|
|
|
- } else {
|
|
|
|
- // TODO better error message
|
|
|
|
- const keyword = this.lexer.literalNames[this.lexerClass.RK_FOR_TO];
|
|
|
|
- throw new Error("Error de sintaxe no comando repeita_para: "+ int_or_id.text + " não é compativel com o esperado para o paramentro "+ keyword + ". O valor deve ser um inteiro ou variável.");
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- parseForPass () {
|
|
|
|
- this.consumeNewLines();
|
|
|
|
- if(this.checkOpenCurly(true)) {
|
|
|
|
- return null;
|
|
|
|
|
|
+ int_or_id = this.getToken();
|
|
}
|
|
}
|
|
- const from_token = this.getToken();
|
|
|
|
- if (from_token.type !== this.lexerClass.RK_FOR_PASS) {
|
|
|
|
- // TODO better error message
|
|
|
|
- const keyword = this.lexer.literalNames[this.lexerClass.RK_FOR_TO];
|
|
|
|
- throw new Error("Error de sintaxe no comando repita_para: esperava-se "+keyword+" mas encontrou "+from_token.text);
|
|
|
|
- }
|
|
|
|
- this.pos += 1;
|
|
|
|
- const int_or_id = this.getToken();
|
|
|
|
|
|
+ let for_from = null;
|
|
if (int_or_id.type === this.lexerClass.ID) {
|
|
if (int_or_id.type === this.lexerClass.ID) {
|
|
- return this.parseID();
|
|
|
|
|
|
+ for_from = new Expressions.VariableLiteral(this.parseID());
|
|
|
|
+ for_from.sourceInfo = SourceInfo.createSourceInfo(int_or_id);
|
|
} else if (int_or_id.type === this.lexerClass.INTEGER) {
|
|
} else if (int_or_id.type === this.lexerClass.INTEGER) {
|
|
this.pos += 1;
|
|
this.pos += 1;
|
|
- return this.getIntLiteral(int_or_id);
|
|
|
|
- } else {
|
|
|
|
|
|
+ for_from = this.getIntLiteral(int_or_id);
|
|
|
|
+ }
|
|
|
|
+ if (for_from == null) {
|
|
// TODO better error message
|
|
// TODO better error message
|
|
- const keyword = this.lexer.literalNames[this.lexerClass.RK_FOR_PASS];
|
|
|
|
|
|
+ const keyword = this.lexer.literalNames[keyword_code];
|
|
throw new Error("Error de sintaxe no comando repeita_para: "+ int_or_id.text + " não é compativel com o esperado para o paramentro "+ keyword + ". O valor deve ser um inteiro ou variável.");
|
|
throw new Error("Error de sintaxe no comando repeita_para: "+ int_or_id.text + " não é compativel com o esperado para o paramentro "+ keyword + ". O valor deve ser um inteiro ou variável.");
|
|
}
|
|
}
|
|
|
|
+ if (is_unary_op) {
|
|
|
|
+ for_from = new Expressions.UnaryApp(convertFromString(op), for_from);
|
|
|
|
+ }
|
|
|
|
+ return for_from;
|
|
}
|
|
}
|
|
|
|
|
|
parseCases () {
|
|
parseCases () {
|