Initial work on compilation to C#
This commit is contained in:
127
UpsilonCompiler/Compiler.cs
Normal file
127
UpsilonCompiler/Compiler.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
17
UpsilonCompiler/UpsilonCompiler.csproj
Normal file
17
UpsilonCompiler/UpsilonCompiler.csproj
Normal 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>
|
||||
Reference in New Issue
Block a user