Initial work on compilation to C#

This commit is contained in:
Deukhoofd 2018-11-13 17:11:20 +01:00
parent b9aac52476
commit bb5d8140e4
No known key found for this signature in database
GPG Key ID: B4C087AC81641654
6 changed files with 165 additions and 6 deletions

View File

@ -6,6 +6,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Yc", "Yc\Yc.csproj", "{EF23
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UpsilonTests", "UpsilonTests\UpsilonTests.csproj", "{5CB3C59D-96A1-419E-803B-DE4A7DF806FD}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UpsilonCompiler", "UpsilonCompiler\UpsilonCompiler.csproj", "{BC98BE8D-D3F5-46CC-9873-51F19D8E05C1}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -24,5 +26,9 @@ Global
{5CB3C59D-96A1-419E-803B-DE4A7DF806FD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5CB3C59D-96A1-419E-803B-DE4A7DF806FD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5CB3C59D-96A1-419E-803B-DE4A7DF806FD}.Release|Any CPU.Build.0 = Release|Any CPU
{BC98BE8D-D3F5-46CC-9873-51F19D8E05C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BC98BE8D-D3F5-46CC-9873-51F19D8E05C1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BC98BE8D-D3F5-46CC-9873-51F19D8E05C1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BC98BE8D-D3F5-46CC-9873-51F19D8E05C1}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal

View File

@ -24,16 +24,19 @@ namespace Upsilon.Evaluator
Evaluator = new Evaluator(this, Diagnostics, variables);
}
public BoundScript Bind()
{
return Binder.BindScript(_parsed);
}
public object Evaluate()
{
var bound = Binder.BindScript(_parsed);
return Evaluator.Evaluate(bound);
return Evaluator.Evaluate(Bind());
}
public T Evaluate<T>()
{
var bound = Binder.BindScript(_parsed);
return (T)Evaluator.Evaluate(bound);
return (T)Evaluator.Evaluate(Bind());
}
}
}

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>

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using Upsilon;
using Upsilon.Binder;
using Upsilon.Evaluator;
using UpsilonCompiler;
namespace Yc
{
@ -34,6 +35,10 @@ namespace Yc
continue;
}
var compiler = new Compiler();
var compiled = compiler.CompileToCSharp(parsed.Bind());
Console.WriteLine(compiled);
/*
var evaluate = parsed.Evaluate();
if (parsed.Diagnostics.Messages.Count > 0)
{
@ -50,7 +55,7 @@ namespace Yc
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine(evaluate);
Console.ResetColor();
}
}*/
}
}

View File

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
@ -6,6 +6,7 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\UpsilonCompiler\UpsilonCompiler.csproj" />
<ProjectReference Include="..\Upsilon\Upsilon.csproj" />
</ItemGroup>