Upsilon/Upsilon/Binder/Binder.cs

91 lines
3.0 KiB
C#
Raw Normal View History

2018-11-11 17:12:42 +00:00
using System;
using System.Runtime.InteropServices;
using Upsilon.BaseTypes.Number;
using Upsilon.Parser;
using Type = Upsilon.BaseTypes.Type;
namespace Upsilon.Binder
{
public class Binder
{
private readonly Diagnostics _diagnostics;
private BoundScope _scope;
public Binder(BoundScope parentScope, Diagnostics diagnostics)
{
_diagnostics = diagnostics;
_scope = new BoundScope(parentScope);
}
public BoundScript BindScript(ScriptSyntax e)
{
var bound = BindExpression(e.Statement);
return new BoundScript(bound);
}
public BoundExpression BindExpression(ExpressionSyntax e)
{
switch (e.Kind)
{
case SyntaxKind.UnaryExpression:
break;
case SyntaxKind.BinaryExpression:
return BindBinaryExpression((BinaryExpressionSyntax) e);
case SyntaxKind.LiteralExpression:
return BindLiteralExpression((LiteralExpressionSyntax) e);
case SyntaxKind.ParenthesizedExpression:
break;
case SyntaxKind.AssignmentExpression:
break;
case SyntaxKind.VariableExpression:
break;
case SyntaxKind.BadExpression:
break;
case SyntaxKind.ScriptUnit:
break;
default:
throw new ArgumentOutOfRangeException();
}
throw new NotImplementedException(e.Kind.ToString());
}
private BoundExpression BindBinaryExpression(BinaryExpressionSyntax e)
{
var left = BindExpression(e.Left);
var right = BindExpression(e.Right);
var op = BoundBinaryOperator.BindBinaryOperator(e.Operator.Kind, left.Type, right.Type);
if (op == null)
{
_diagnostics.LogUnknownOperator(e.Span, e.Operator.Kind, left.Type, right.Type);
return left;
}
return new BoundBinaryExpression(op, left, right, op.OutType);
}
private BoundExpression BindLiteralExpression(LiteralExpressionSyntax e)
{
var value = e.Value;
var type = Type.Nil;
object outValue = null;
switch (value)
{
case double d:
2018-11-11 17:19:30 +00:00
type = Type.Number;
2018-11-11 17:12:42 +00:00
outValue = new NumberDouble(d);
break;
2018-11-11 17:19:30 +00:00
case long l:
type = Type.Number;
outValue = new NumberLong(l);
break;
2018-11-11 17:12:42 +00:00
case bool b:
type = Type.Boolean;
outValue = value;
break;
default:
_diagnostics.LogUnknownType(e.Span);
break;
}
return new BoundLiteralExpression(outValue, type);
}
}
}