Initial work on compilation to C#

This commit is contained in:
2018-11-13 17:11:20 +01:00
parent b9aac52476
commit bb5d8140e4
6 changed files with 165 additions and 6 deletions

127
UpsilonCompiler/Compiler.cs Normal file
View File

@@ -0,0 +1,127 @@
using System;
using System.Text;
using Upsilon.BaseTypes.Number;
using Upsilon.Binder;
using System.Collections.Immutable;
using Type = Upsilon.BaseTypes.Type;
namespace UpsilonCompiler
{
public class Compiler
{
public string CompileToCSharp(BoundScript script)
{
var s = script.Statement;
return Compile(s);
}
private string Compile(BoundNode e)
{
switch (e.Kind)
{
case BoundKind.BoundScript:
throw new ArgumentOutOfRangeException();
case BoundKind.BoundLiteralExpression:
return CompileLiteralExpression((BoundLiteralExpression) e);
case BoundKind.BoundBinaryExpression:
return CompileBinaryExpression((BoundBinaryExpression) e);
case BoundKind.BoundUnaryExpression:
case BoundKind.VariableExpression:
case BoundKind.BoundAssignmentStatement:
throw new ArgumentOutOfRangeException();
case BoundKind.BoundExpressionStatement:
return Compile(((BoundExpressionStatement)e).Expression);
case BoundKind.BoundBlockStatement:
return CompileBlockStatement((BoundBlockStatement) e);
case BoundKind.BoundIfStatement:
return CompileIfStatement((BoundIfStatement) e);
case BoundKind.BoundElseStatement:
default:
throw new ArgumentOutOfRangeException(e.Kind.ToString());
}
}
private string CompileBlockStatement(BoundBlockStatement s)
{
var sb = new StringBuilder();
foreach (var sStatement in s.Statements)
{
var compile = Compile(sStatement);
sb.Append(compile);
sb.Append(";\n");
}
return sb.ToString();
}
private string CompileLiteralExpression(BoundLiteralExpression e)
{
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();
}
}
private string CompileBinaryExpression(BoundBinaryExpression e)
{
var sb = new StringBuilder();
sb.Append("(");
var compiledLeft = Compile(e.LeftExpression);
var compiledRight = Compile(e.RightExpression);
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();
}
private string CompileIfStatement(BoundIfStatement s, bool isElseIf = false)
{
var sb = new StringBuilder();
var openToken = isElseIf ? "else if(" : "if(";
sb.Append(openToken);
var compiledCondition = Compile(s.Condition);
sb.Append(compiledCondition);
sb.Append("){\n");
var compiledBlock = Compile(s.Block);
sb.Append(compiledBlock);
sb.Append("}");
return sb.ToString();
}
}
}

View File

@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace>UpsilonCompiler</RootNamespace>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Upsilon\Upsilon.csproj" />
</ItemGroup>
<ItemGroup>
<Reference Include="System.Collections.Immutable, Version=1.2.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<HintPath>..\..\..\..\..\usr\share\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.1.0\ref\netcoreapp2.1\System.Collections.Immutable.dll</HintPath>
</Reference>
</ItemGroup>
</Project>