in Iris/IrisCompiler/FrontEnd/Translator.cs [88:169]
protected void ParseProgram()
{
string programName = "program";
if (Accept(Token.KwProgram))
{
if (Accept(Token.Identifier))
programName = _lexeme;
else
AddErrorAtTokenStart("Expecting program name.");
Expect(Token.ChrSemicolon);
}
_context.Emitter.BeginProgram(programName, _context.Importer.ImportedAssemblies);
List<Tuple<Variable, FilePosition>> globals = new List<Tuple<Variable, FilePosition>>();
if (Accept(Token.KwVar))
{
ParseVariableList(globals, isArgumentList: false);
foreach (Tuple<Variable, FilePosition> globalDecl in globals)
{
Variable global = globalDecl.Item1;
if (ValidateName(globalDecl.Item2, global.Name, global: true))
{
Symbol globalSymbol = _symbolTable.Add(global.Name, global.Type, StorageClass.Global);
_context.Emitter.DeclareGlobal(globalSymbol);
}
}
}
FilePosition blockBegin = _lexer.TokenStartPosition;
while (!Accept(Token.KwBegin))
{
if (Accept(Token.Eof))
{
AddErrorAtLastParsedPosition("Unexpected end of file looking for main block.");
return;
}
else if (Accept(Token.KwFunction))
{
ParseMethod(isFunction: true);
}
else if (Accept(Token.KwProcedure))
{
ParseMethod(isFunction: false);
}
else if (Accept(Token.KwVar))
{
AddErrorAtTokenStart("Global variables must be declared before the first function or procedure.");
List<Tuple<Variable, FilePosition>> unused = new List<Tuple<Variable, FilePosition>>();
ParseVariableList(unused, isArgumentList: false);
}
else if (!Accept(Token.ChrSemicolon))
{
AddErrorAtTokenStart("Expecting 'function', 'procedure', or 'begin'.");
SkipToNextEnd();
}
blockBegin = _lexer.TokenStartPosition;
}
// We are now at the main block
IrisType mainMethod = Procedure.Create(new Variable[0]);
Symbol mainSymbol = _symbolTable.OpenMethod("$.main", mainMethod);
MethodGenerator.BeginMethod(mainSymbol.Name, IrisType.Void, new Variable[0], new Variable[0], true, _context.FilePath);
MethodGenerator.EmitNonCodeLineInfo(blockBegin.Expand(5 /* Length of "begin" */));
// Initialize global variables if needed
foreach (Tuple<Variable, FilePosition> globalDecl in globals)
InitializeVariableIfNeeded(blockBegin, globalDecl.Item1);
ParseStatements(Token.KwEnd);
MethodGenerator.EndMethod();
Accept(Token.ChrPeriod);
Expect(Token.Eof);
_context.Emitter.EndProgram();
}