blob: 524ef8d87fcce323c317916af2288aa61eb1eb1c (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
using AtLangCompiler.ILEmitter;
using System.Reflection.Emit;
namespace AtLangCompiler.Methods;
internal class PrintToken : ILexerTokenConfig
{
public IReadOnlyDictionary<string, TokenType> TokenStrings => new Dictionary<string, TokenType>
{
{ "@print", TokenType.PRINT }
};
}
internal class PrintStatement : ASTNode
{
public ASTNode Expr { get; }
public PrintStatement(ASTNode expr) { Expr = expr; }
}
[ParserFor(TokenType.PRINT, inputTokens: 1)]
internal class PrintStatementParser : IStatementParser
{
public ASTNode ParseStatement(Parser parser)
{
parser.Eat(TokenType.PRINT);
parser.Eat(TokenType.LPAREN);
ASTNode expr = parser.ParseExpression();
parser.Eat(TokenType.RPAREN);
return new PrintStatement(expr);
}
}
[EmitterFor(typeof(PrintStatement))]
internal class Print : IMethodEmitter<PrintStatement>
{
private readonly ILGenerator il;
private readonly LocalBuilder dictLocal;
private readonly ILMethodEmitterManager emitter;
public Print(ILGenerator il, LocalBuilder dictLocal, ILMethodEmitterManager emitter)
{
this.il = il ?? throw new ArgumentNullException(nameof(il));
this.dictLocal = dictLocal ?? throw new ArgumentNullException(nameof(dictLocal));
this.emitter = emitter ?? throw new ArgumentNullException(nameof(emitter));
}
public void EmitIL(PrintStatement node)
{
// Console.Out.WriteLine( Evaluate(ps.Expr) )
il.Emit(OpCodes.Call, typeof(Console).GetMethod("get_Out")!);
emitter.EmitStatement(node.Expr);
il.Emit(OpCodes.Callvirt,
typeof(TextWriter).GetMethod(nameof(TextWriter.WriteLine), [typeof(string)])!);
}
}
|