|
@@ -891,21 +891,21 @@ export class IVProgParser {
|
|
|
|
|
|
parseFor () {
|
|
parseFor () {
|
|
this.pushScope(IVProgParser.BREAKABLE);
|
|
this.pushScope(IVProgParser.BREAKABLE);
|
|
- this.pos++;
|
|
|
|
- this.checkOpenParenthesis();
|
|
|
|
- this.pos++;
|
|
|
|
- this.consumeNewLines();
|
|
|
|
- const attribution = this.parseForAssign();
|
|
|
|
- this.consumeNewLines();
|
|
|
|
- const condition = this.parseExpressionOR();
|
|
|
|
- this.consumeForSemiColon();
|
|
|
|
- const increment = this.parseForAssign(true);
|
|
|
|
- this.checkCloseParenthesis()
|
|
|
|
- this.pos++;
|
|
|
|
|
|
+ const for_token = this.getToken();
|
|
|
|
+ this.pos += 1;
|
|
|
|
+ const for_id = this.parseID();
|
|
|
|
+ const for_from = this.parseForFrom();
|
|
|
|
+ const for_to = this.parseForTo();
|
|
|
|
+ let maybePass = this.parseForPass();
|
|
|
|
+ if (maybePass == null) {
|
|
|
|
+ maybePass = new Expressions.IntLiteral(toInt(1));
|
|
|
|
+ }
|
|
this.consumeNewLines();
|
|
this.consumeNewLines();
|
|
const commandsBlock = this.parseCommandBlock();
|
|
const commandsBlock = this.parseCommandBlock();
|
|
this.popScope();
|
|
this.popScope();
|
|
- return new Commands.For(attribution, condition, increment, commandsBlock);
|
|
|
|
|
|
+ const cmd = new Commands.For(for_id, for_from, for_to, maybePass, commandsBlock);
|
|
|
|
+ cmd.sourceInfo = SourceInfo.createSourceInfo(for_token);
|
|
|
|
+ return cmd;
|
|
}
|
|
}
|
|
|
|
|
|
parseWhile () {
|
|
parseWhile () {
|
|
@@ -999,26 +999,71 @@ export class IVProgParser {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- parseForAssign (isLast = false) {
|
|
|
|
- if(!isLast)
|
|
|
|
- this.consumeNewLines();
|
|
|
|
- if(this.checkEOS(true)) {
|
|
|
|
|
|
+ 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.");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ parseForTo () {
|
|
|
|
+ const from_token = this.getToken();
|
|
|
|
+ if (from_token.type !== this.lexerClass.RK_FOR_TO) {
|
|
|
|
+ // 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();
|
|
|
|
+ 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_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;
|
|
return null;
|
|
}
|
|
}
|
|
- const id = this.parseID();
|
|
|
|
- const equal = this.getToken();
|
|
|
|
- if (equal.type !== this.lexerClass.EQUAL) {
|
|
|
|
- throw SyntaxErrorFactory.token_missing_one('=', equal);
|
|
|
|
|
|
+ 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++
|
|
|
|
- const exp = this.parseExpressionOR();
|
|
|
|
- if(!isLast) {
|
|
|
|
- this.consumeForSemiColon();
|
|
|
|
|
|
+ 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_PASS];
|
|
|
|
+ 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.");
|
|
}
|
|
}
|
|
- const sourceInfo = SourceInfo.createSourceInfo(equal);
|
|
|
|
- const cmd = new Commands.Assign(id, exp);
|
|
|
|
- cmd.sourceInfo = sourceInfo;
|
|
|
|
- return cmd;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
parseCases () {
|
|
parseCases () {
|
|
@@ -1318,4 +1363,4 @@ export class IVProgParser {
|
|
const types = this.insideScope(IVProgParser.FUNCTION) ? this.functionTypes : this.variableTypes;
|
|
const types = this.insideScope(IVProgParser.FUNCTION) ? this.functionTypes : this.variableTypes;
|
|
return types.map( x => this.lexer.literalNames[x]);
|
|
return types.map( x => this.lexer.literalNames[x]);
|
|
}
|
|
}
|
|
-}
|
|
|
|
|
|
+}
|