public void Compile( CodeBlock statement, ICompilationContext context ) { context.Symbols.PushLocalScope(); foreach (var subStatement in statement.Statements) { switch (subStatement) { case CodeBlock codeBlock: Compile(codeBlock, context); break; case Declaration declaration: context.CompileStatement(declaration); break; case For @for: context.CompileStatement(@for); break; case If @if: context.CompileStatement(@if); break; case While @while: context.CompileStatement(@while); break; case Return @return: context.CompileStatement(@return); break; case IExpression expression: context.CompileExpression( expression, new PreferredRegister(Register64.RAX, XmmRegister.XMM0) ); break; default: throw new NotImplementedException( $"{nameof(CodeBlockCompiler)}: I do not know how to compile: {subStatement.GetType().Name}" ); } } context.Symbols.PopLocalScope(); }
public void Compile( For statement, ICompilationContext context ) { context.Symbols.PushLocalScope(); context.CompileStatement(statement.Variable); var bodyAndIncrement = statement.Instruction.StatementAsBlock().Statements.Concat(new[] { statement.Increment }).ToArray(); var equalWhile = new While(statement.Condition, new CodeBlock(bodyAndIncrement)); _whileCompiler.Compile(equalWhile, context); context.Symbols.PopLocalScope(); }
private void CompileFunction(FunctionImplementation function, ICompilationContext context) { foreach (var parameter in function.Declaration.Parameters) { context.Symbols.DefineLocal(parameter.ParameterIdentifier.RawText, parameter.ParameterType); } if (function.Declaration.Identifier.RawText == "Main") { context.Generator.CallDereferenced4(Constants.DummyOffsetInt); context.Linking.FixIATEntryOffset(context.Generator.StreamPosition, "kernel32.dll", "GetProcessHeap"); context.Generator.MovToDereferenced4(Constants.DummyOffsetInt, Register64.RAX); context.Linking.FixDataOffset(context.Generator.StreamPosition, Constants.HeapHandleIdentifier); } context.CompileStatement(function.Body.StatementAsBlock()); context.Generator.InsertCode(context.Linking, 0, gen => context.Storage.CreatePrologue(gen, function.Declaration)); context.Linking.ResolveFunctionEpilogueFixes(function.Declaration.Identifier.RawText, context.Generator.StreamPosition); context.Storage.CreateEpilogue(context.Generator); context.Generator.Ret(); }