视频与PR:https://github.com/terrajobst/minsk/blob/master/docs/episode-02.md
作者是 Immo Landwerth(https://twitter.com/terrajobst),微软 .NET 团队的项目经理。
这一集的主要内容:
1.添加 Binder,充当语义分析作用。
Binder 基于 SyntaxTree,大体上 SyntaxKind.XXX_Expression => Bind_XXX_Expression。
在 SyntaxTree 中,运算符只是个枚举值(即也就只是个符号),而在 Binder 中必须赋予更加具体的语义。
比如:
> SyntaxKind.PlusToken => BoundBinaryOperatorKind.Addition (“+”代表累加)
> SyntaxKind.AmpersandAmpersandToken => BoundBinaryOperatorKind.LogicalAnd(“&&”代表逻辑与)
在 Binder 中,运算符有更加宽泛的含义,如果是二元运算符,必须可以获取其符号的 SyntaxKind、BoundBinaryOperatorKind、LeftType、RightType、ResultType。计算结果的类型代表了该二元表达式的类型。
以 BoundBinaryOperator 作为具体实现:
using System; using Minsk.CodeAnalysis.Syntax; namespace Minsk.CodeAnalysis.Binding { internal sealed class BoundBinaryOperator { private BoundBinaryOperator(SyntaxKind syntaxKind, BoundBinaryOperatorKind kind, Type type) : this(syntaxKind, kind, type, type, type) { } private BoundBinaryOperator(SyntaxKind syntaxKind, BoundBinaryOperatorKind kind, Type operandType, Type resultType) : this(syntaxKind, kind, operandType, operandType, resultType) { } private BoundBinaryOperator(SyntaxKind syntaxKind, BoundBinaryOperatorKind kind, Type leftType, Type rightType, Type resultType) { SyntaxKind = syntaxKind; Kind = kind; LeftType = leftType; RightType = rightType; Type = resultType; } public SyntaxKind SyntaxKind { get; } public BoundBinaryOperatorKind Kind { get; } public Type LeftType { get; } public Type RightType { get; } public Type Type { get; } private static BoundBinaryOperator[] _operators = { new BoundBinaryOperator(SyntaxKind.PlusToken, BoundBinaryOperatorKind.Addition, typeof(int)), new BoundBinaryOperator(SyntaxKind.MinusToekn, BoundBinaryOperatorKind.Subtraction, typeof(int)), new BoundBinaryOperator(SyntaxKind.StarToken, BoundBinaryOperatorKind.Multiplication, typeof(int)), new BoundBinaryOperator(SyntaxKind.SlashToken, BoundBinaryOperatorKind.Division, typeof(int)), new BoundBinaryOperator(SyntaxKind.EqualsEqualsToken, BoundBinaryOperatorKind.Equals, typeof(int), typeof(bool)), new BoundBinaryOperator(SyntaxKind.BangEqualsToken, BoundBinaryOperatorKind.NotEquals, typeof(int), typeof(bool)), new BoundBinaryOperator(SyntaxKind.AmpersandAmpersandToken, BoundBinaryOperatorKind.LogicalAnd, typeof(bool)), new BoundBinaryOperator(SyntaxKind.PipePipeToken, BoundBinaryOperatorKind.LogicalOr, typeof(bool)), new BoundBinaryOperator(SyntaxKind.EqualsEqualsToken, BoundBinaryOperatorKind.Equals, typeof(bool)), new BoundBinaryOperator(SyntaxKind.BangEqualsToken, BoundBinaryOperatorKind.NotEquals, typeof(bool)), }; public static BoundBinaryOperator Bind(SyntaxKind syntaxKind, Type leftType, Type rightType) { foreach (var op in _operators) { if (op.SyntaxKind == syntaxKind && op.LeftType == leftType && op.RightType == rightType) return op; } return null; } } }
以及 BoundBinaryExpression 的实现:
using System; namespace Minsk.CodeAnalysis.Binding { internal sealed class BoundBinaryExpression : BoundExpression { public BoundBinaryExpression(BoundExpression left, BoundBinaryOperator op,