Upsilon/UpsilonCompiler/Compiler.cs

126 lines
4.4 KiB
C#
Raw Normal View History

2018-11-13 16:11:20 +00:00
using System;
using System.Text;
using Upsilon.BaseTypes.Number;
using Upsilon.Binder;
using Type = Upsilon.BaseTypes.Type;
namespace UpsilonCompiler
{
2018-11-14 11:44:44 +00:00
public class Transpiler
2018-11-13 16:11:20 +00:00
{
2018-11-14 11:44:44 +00:00
public string TranspilerToCSharp(BoundScript script)
2018-11-13 16:11:20 +00:00
{
var s = script.Statement;
2018-11-14 11:44:44 +00:00
return Transpile(s);
2018-11-13 16:11:20 +00:00
}
2018-11-14 11:44:44 +00:00
private string Transpile(BoundNode e)
2018-11-13 16:11:20 +00:00
{
switch (e.Kind)
{
case BoundKind.BoundScript:
throw new ArgumentOutOfRangeException();
case BoundKind.BoundLiteralExpression:
2018-11-14 11:44:44 +00:00
return TranspileLiteralExpression((BoundLiteralExpression) e);
2018-11-13 16:11:20 +00:00
case BoundKind.BoundBinaryExpression:
2018-11-14 11:44:44 +00:00
return TranspileBinaryExpression((BoundBinaryExpression) e);
2018-11-13 16:11:20 +00:00
case BoundKind.BoundUnaryExpression:
case BoundKind.VariableExpression:
case BoundKind.BoundAssignmentStatement:
throw new ArgumentOutOfRangeException();
case BoundKind.BoundExpressionStatement:
2018-11-14 11:44:44 +00:00
return Transpile(((BoundExpressionStatement)e).Expression);
2018-11-13 16:11:20 +00:00
case BoundKind.BoundBlockStatement:
2018-11-14 11:44:44 +00:00
return TranspileBlockStatement((BoundBlockStatement) e);
2018-11-13 16:11:20 +00:00
case BoundKind.BoundIfStatement:
2018-11-14 11:44:44 +00:00
return TranspileIfStatement((BoundIfStatement) e);
2018-11-13 16:11:20 +00:00
case BoundKind.BoundElseStatement:
default:
throw new ArgumentOutOfRangeException(e.Kind.ToString());
}
}
2018-11-14 11:44:44 +00:00
private string TranspileBlockStatement(BoundBlockStatement s)
2018-11-13 16:11:20 +00:00
{
var sb = new StringBuilder();
foreach (var sStatement in s.Statements)
{
2018-11-14 11:44:44 +00:00
var compile = Transpile(sStatement);
2018-11-13 16:11:20 +00:00
sb.Append(compile);
sb.Append(";\n");
}
return sb.ToString();
}
2018-11-14 11:44:44 +00:00
private static string TranspileLiteralExpression(BoundLiteralExpression e)
2018-11-13 16:11:20 +00:00
{
switch (e.Type)
{
case Type.Nil:
return "null";
case Type.Boolean:
return ((bool)e.Value) ? "true" : "false";
case Type.Number:
return ((Number) e.Value).ToString();
case Type.String:
case Type.Function:
case Type.UserData:
case Type.Thread:
case Type.Table:
default:
throw new ArgumentOutOfRangeException();
}
}
2018-11-14 11:44:44 +00:00
private string TranspileBinaryExpression(BoundBinaryExpression e)
2018-11-13 16:11:20 +00:00
{
var sb = new StringBuilder();
sb.Append("(");
2018-11-14 11:44:44 +00:00
var compiledLeft = Transpile(e.LeftExpression);
var compiledRight = Transpile(e.RightExpression);
2018-11-13 16:11:20 +00:00
sb.Append(compiledLeft);
switch (e.Operator.Kind)
{
case BoundBinaryOperator.OperatorKind.Addition:
sb.Append("+");
break;
case BoundBinaryOperator.OperatorKind.Subtraction:
sb.Append("-");
break;
case BoundBinaryOperator.OperatorKind.Multiplication:
sb.Append("*");
break;
case BoundBinaryOperator.OperatorKind.Division:
sb.Append("/");
break;
case BoundBinaryOperator.OperatorKind.Equality:
sb.Append("==");
break;
case BoundBinaryOperator.OperatorKind.Inequality:
sb.Append("!=");
break;
default:
throw new ArgumentOutOfRangeException();
}
sb.Append(compiledRight);
sb.Append(")");
return sb.ToString();
}
2018-11-14 11:44:44 +00:00
private string TranspileIfStatement(BoundIfStatement s, bool isElseIf = false)
2018-11-13 16:11:20 +00:00
{
var sb = new StringBuilder();
var openToken = isElseIf ? "else if(" : "if(";
sb.Append(openToken);
2018-11-14 11:44:44 +00:00
var compiledCondition = Transpile(s.Condition);
2018-11-13 16:11:20 +00:00
sb.Append(compiledCondition);
sb.Append("){\n");
2018-11-14 11:44:44 +00:00
var compiledBlock = Transpile(s.Block);
2018-11-13 16:11:20 +00:00
sb.Append(compiledBlock);
sb.Append("}");
return sb.ToString();
}
}
}