CodeGenerator 0
This commit is contained in:
Родитель
9392dae0a9
Коммит
a3f9fca0d9
|
@ -0,0 +1,10 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Pchp.CodeAnalysis.Semantics
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Pchp.CodeAnalysis.Semantics
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
|
@ -9,6 +9,7 @@ using Microsoft.CodeAnalysis.Emit;
|
||||||
using Pchp.CodeAnalysis.Emit;
|
using Pchp.CodeAnalysis.Emit;
|
||||||
using Pchp.CodeAnalysis.FlowAnalysis;
|
using Pchp.CodeAnalysis.FlowAnalysis;
|
||||||
using Pchp.CodeAnalysis.Symbols;
|
using Pchp.CodeAnalysis.Symbols;
|
||||||
|
using Pchp.CodeAnalysis.Semantics.Graph;
|
||||||
|
|
||||||
namespace Pchp.CodeAnalysis.CodeGen
|
namespace Pchp.CodeAnalysis.CodeGen
|
||||||
{
|
{
|
||||||
|
@ -44,10 +45,37 @@ namespace Pchp.CodeAnalysis.CodeGen
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Emits routines body.
|
||||||
|
/// </summary>
|
||||||
|
public void Generate()
|
||||||
|
{
|
||||||
|
Generate(_routine.ControlFlowGraph.Start);
|
||||||
|
|
||||||
|
// DEBUG
|
||||||
|
|
||||||
|
_il.EmitNullConstant();
|
||||||
|
_il.EmitRet(false);
|
||||||
|
|
||||||
|
// DEBUG
|
||||||
|
|
||||||
|
_il.AssertStackEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Emits given block and recursively its edge if it was not emitted already.
|
||||||
|
/// </summary>
|
||||||
|
void Generate(BoundBlock block)
|
||||||
|
{
|
||||||
|
Contract.ThrowIfNull(block);
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Emit cast from one type to another.
|
/// Emit cast from one type to another.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal void EmitCast(INamedTypeSymbol from, INamedTypeSymbol to)
|
public void EmitCast(INamedTypeSymbol from, INamedTypeSymbol to)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,19 +83,14 @@ namespace Pchp.CodeAnalysis.CodeGen
|
||||||
// asyncDebugInfo = new Cci.AsyncMethodBodyDebugInfo(kickoffMethod, kickoffMethod.ReturnsVoid ? asyncCatchHandlerOffset : -1, asyncYieldPoints, asyncResumePoints);
|
// asyncDebugInfo = new Cci.AsyncMethodBodyDebugInfo(kickoffMethod, kickoffMethod.ReturnsVoid ? asyncCatchHandlerOffset : -1, asyncYieldPoints, asyncResumePoints);
|
||||||
//}
|
//}
|
||||||
//else
|
//else
|
||||||
//{
|
{
|
||||||
// codeGen.Generate();
|
codeGen.Generate();
|
||||||
//}
|
}
|
||||||
|
|
||||||
// DEBUG
|
|
||||||
|
|
||||||
builder.EmitNullConstant();
|
|
||||||
builder.EmitRet(false);
|
|
||||||
|
|
||||||
|
//
|
||||||
builder.Realize();
|
builder.Realize();
|
||||||
|
|
||||||
// DEBUG
|
//
|
||||||
|
|
||||||
var localVariables = builder.LocalSlotManager.LocalsInOrder();
|
var localVariables = builder.LocalSlotManager.LocalsInOrder();
|
||||||
|
|
||||||
if (localVariables.Length > 0xFFFE)
|
if (localVariables.Length > 0xFFFE)
|
||||||
|
|
|
@ -55,7 +55,9 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="CodeGen\BoundVariable.cs" />
|
<Compile Include="CodeGen\BoundVariable.cs" />
|
||||||
<Compile Include="CodeGen\CodeGenerator.cs" />
|
<Compile Include="CodeGen\CodeGenerator.cs" />
|
||||||
|
<Compile Include="CodeGen\BoundExpression.cs" />
|
||||||
<Compile Include="CodeGen\Places.cs" />
|
<Compile Include="CodeGen\Places.cs" />
|
||||||
|
<Compile Include="CodeGen\BoundStatement.cs" />
|
||||||
<Compile Include="Compilation\SourceCompiler.cs" />
|
<Compile Include="Compilation\SourceCompiler.cs" />
|
||||||
<Compile Include="Emitter\Model\FieldSymbolAdapter.cs" />
|
<Compile Include="Emitter\Model\FieldSymbolAdapter.cs" />
|
||||||
<Compile Include="FlowAnalysis\FlowContext.cs" />
|
<Compile Include="FlowAnalysis\FlowContext.cs" />
|
||||||
|
@ -73,7 +75,7 @@
|
||||||
<Compile Include="FlowAnalysis\Visitors\LocalsWalker.cs" />
|
<Compile Include="FlowAnalysis\Visitors\LocalsWalker.cs" />
|
||||||
<Compile Include="FlowAnalysis\Worklist.cs" />
|
<Compile Include="FlowAnalysis\Worklist.cs" />
|
||||||
<Compile Include="Semantics\BoundVariable.cs" />
|
<Compile Include="Semantics\BoundVariable.cs" />
|
||||||
<Compile Include="Semantics\Expressions.cs" />
|
<Compile Include="Semantics\BoundExpression.cs" />
|
||||||
<Compile Include="Semantics\ExpressionsExtension.cs" />
|
<Compile Include="Semantics\ExpressionsExtension.cs" />
|
||||||
<Compile Include="Semantics\Graph\BoundBlock.cs" />
|
<Compile Include="Semantics\Graph\BoundBlock.cs" />
|
||||||
<Compile Include="Semantics\Graph\BuilderVisitor.cs" />
|
<Compile Include="Semantics\Graph\BuilderVisitor.cs" />
|
||||||
|
@ -81,7 +83,7 @@
|
||||||
<Compile Include="Semantics\Graph\Edge.cs" />
|
<Compile Include="Semantics\Graph\Edge.cs" />
|
||||||
<Compile Include="Semantics\Graph\GraphVisitor.cs" />
|
<Compile Include="Semantics\Graph\GraphVisitor.cs" />
|
||||||
<Compile Include="Semantics\SemanticsBinder.cs" />
|
<Compile Include="Semantics\SemanticsBinder.cs" />
|
||||||
<Compile Include="Semantics\Statements.cs" />
|
<Compile Include="Semantics\BoundStatement.cs" />
|
||||||
<Compile Include="CodeGen\MethodGenerator.cs" />
|
<Compile Include="CodeGen\MethodGenerator.cs" />
|
||||||
<Compile Include="CommandLine\PhpCommandLineArguments.cs" />
|
<Compile Include="CommandLine\PhpCommandLineArguments.cs" />
|
||||||
<Compile Include="CommandLine\PhpCommandLineParser.cs" />
|
<Compile Include="CommandLine\PhpCommandLineParser.cs" />
|
||||||
|
|
|
@ -45,7 +45,7 @@ namespace Pchp.CodeAnalysis.Semantics
|
||||||
|
|
||||||
#region BoundExpression
|
#region BoundExpression
|
||||||
|
|
||||||
public abstract class BoundExpression : IExpression
|
public abstract partial class BoundExpression : IExpression
|
||||||
{
|
{
|
||||||
public TypeRefMask TypeRefMask { get; set; } = default(TypeRefMask);
|
public TypeRefMask TypeRefMask { get; set; } = default(TypeRefMask);
|
||||||
|
|
||||||
|
@ -70,26 +70,55 @@ namespace Pchp.CodeAnalysis.Semantics
|
||||||
|
|
||||||
#region BoundFunctionCall
|
#region BoundFunctionCall
|
||||||
|
|
||||||
|
public partial class BoundArgument : IArgument
|
||||||
|
{
|
||||||
|
public ArgumentKind ArgumentKind => ArgumentKind.Positional; // TODO: DefaultValue, ParamArray
|
||||||
|
|
||||||
|
public IExpression InConversion => null;
|
||||||
|
|
||||||
|
public bool IsInvalid => false;
|
||||||
|
|
||||||
|
public OperationKind Kind => OperationKind.Argument;
|
||||||
|
|
||||||
|
public IExpression OutConversion => null;
|
||||||
|
|
||||||
|
public IParameterSymbol Parameter { get; set; }
|
||||||
|
|
||||||
|
public SyntaxNode Syntax => null;
|
||||||
|
|
||||||
|
public IExpression Value { get; set; }
|
||||||
|
|
||||||
|
public BoundArgument(BoundExpression value)
|
||||||
|
{
|
||||||
|
this.Value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Accept(OperationVisitor visitor)
|
||||||
|
=> visitor.VisitArgument(this);
|
||||||
|
|
||||||
|
public TResult Accept<TArgument, TResult>(OperationVisitor<TArgument, TResult> visitor, TArgument argument)
|
||||||
|
=> visitor.VisitArgument(this, argument);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a function call.
|
/// Represents a function call.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class BoundFunctionCall : BoundExpression, IInvocationExpression
|
public partial class BoundFunctionCall : BoundExpression, IInvocationExpression
|
||||||
{
|
{
|
||||||
protected ImmutableArray<BoundExpression> _arguments;
|
protected ImmutableArray<BoundArgument> _arguments;
|
||||||
|
|
||||||
public ImmutableArray<IArgument> ArgumentsInParameterOrder => ArgumentsInSourceOrder;
|
public ImmutableArray<IArgument> ArgumentsInParameterOrder => ArgumentsInSourceOrder;
|
||||||
|
|
||||||
public ImmutableArray<IArgument> ArgumentsInSourceOrder
|
public ImmutableArray<IArgument> ArgumentsInSourceOrder => StaticCast<IArgument>.From(_arguments);
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public IArgument ArgumentMatchingParameter(IParameterSymbol parameter)
|
public IArgument ArgumentMatchingParameter(IParameterSymbol parameter)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
foreach (var arg in _arguments)
|
||||||
|
if (arg.Parameter == parameter)
|
||||||
|
return arg;
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual IExpression Instance => null;
|
public virtual IExpression Instance => null;
|
||||||
|
@ -100,6 +129,12 @@ namespace Pchp.CodeAnalysis.Semantics
|
||||||
|
|
||||||
public IMethodSymbol TargetMethod { get; set; }
|
public IMethodSymbol TargetMethod { get; set; }
|
||||||
|
|
||||||
|
public BoundFunctionCall(ImmutableArray<BoundArgument> arguments)
|
||||||
|
{
|
||||||
|
Debug.Assert(!arguments.IsDefault);
|
||||||
|
_arguments = arguments;
|
||||||
|
}
|
||||||
|
|
||||||
public override void Accept(OperationVisitor visitor)
|
public override void Accept(OperationVisitor visitor)
|
||||||
=> visitor.VisitInvocationExpression(this);
|
=> visitor.VisitInvocationExpression(this);
|
||||||
|
|
||||||
|
@ -111,11 +146,11 @@ namespace Pchp.CodeAnalysis.Semantics
|
||||||
|
|
||||||
#region BoundEcho
|
#region BoundEcho
|
||||||
|
|
||||||
public sealed class BoundEcho : BoundFunctionCall
|
public sealed partial class BoundEcho : BoundFunctionCall
|
||||||
{
|
{
|
||||||
public BoundEcho(ImmutableArray<BoundExpression> arguments)
|
public BoundEcho(ImmutableArray<BoundArgument> arguments)
|
||||||
|
:base(arguments)
|
||||||
{
|
{
|
||||||
_arguments = arguments;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,7 +158,7 @@ namespace Pchp.CodeAnalysis.Semantics
|
||||||
|
|
||||||
#region BoundLiteral
|
#region BoundLiteral
|
||||||
|
|
||||||
public class BoundLiteral : BoundExpression, ILiteralExpression
|
public partial class BoundLiteral : BoundExpression, ILiteralExpression
|
||||||
{
|
{
|
||||||
Optional<object> _value;
|
Optional<object> _value;
|
||||||
|
|
||||||
|
@ -149,7 +184,7 @@ namespace Pchp.CodeAnalysis.Semantics
|
||||||
|
|
||||||
#region BoundBinaryEx
|
#region BoundBinaryEx
|
||||||
|
|
||||||
public sealed class BoundBinaryEx : BoundExpression, IBinaryOperatorExpression
|
public sealed partial class BoundBinaryEx : BoundExpression, IBinaryOperatorExpression
|
||||||
{
|
{
|
||||||
public BinaryOperationKind BinaryOperationKind { get; private set; }
|
public BinaryOperationKind BinaryOperationKind { get; private set; }
|
||||||
|
|
||||||
|
@ -181,7 +216,7 @@ namespace Pchp.CodeAnalysis.Semantics
|
||||||
|
|
||||||
#region BoundAssignEx, BoundCompoundAssignEx
|
#region BoundAssignEx, BoundCompoundAssignEx
|
||||||
|
|
||||||
public class BoundAssignEx : BoundExpression, IAssignmentExpression
|
public partial class BoundAssignEx : BoundExpression, IAssignmentExpression
|
||||||
{
|
{
|
||||||
public override OperationKind Kind => OperationKind.AssignmentExpression;
|
public override OperationKind Kind => OperationKind.AssignmentExpression;
|
||||||
|
|
||||||
|
@ -202,7 +237,7 @@ namespace Pchp.CodeAnalysis.Semantics
|
||||||
=> visitor.VisitAssignmentExpression(this, argument);
|
=> visitor.VisitAssignmentExpression(this, argument);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class BoundCompoundAssignEx : BoundAssignEx, ICompoundAssignmentExpression
|
public partial class BoundCompoundAssignEx : BoundAssignEx, ICompoundAssignmentExpression
|
||||||
{
|
{
|
||||||
public BinaryOperationKind BinaryKind { get; private set; }
|
public BinaryOperationKind BinaryKind { get; private set; }
|
||||||
|
|
||||||
|
@ -229,7 +264,7 @@ namespace Pchp.CodeAnalysis.Semantics
|
||||||
|
|
||||||
#region BoundReferenceExpression
|
#region BoundReferenceExpression
|
||||||
|
|
||||||
public abstract class BoundReferenceExpression : BoundExpression, IReferenceExpression
|
public abstract partial class BoundReferenceExpression : BoundExpression, IReferenceExpression
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -241,7 +276,7 @@ namespace Pchp.CodeAnalysis.Semantics
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A variable reference that can be read or written to.
|
/// A variable reference that can be read or written to.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class BoundVariableRef : BoundReferenceExpression, ILocalReferenceExpression
|
public partial class BoundVariableRef : BoundReferenceExpression, ILocalReferenceExpression
|
||||||
{
|
{
|
||||||
readonly string _name;
|
readonly string _name;
|
||||||
BoundVariable _variable;
|
BoundVariable _variable;
|
|
@ -14,7 +14,7 @@ namespace Pchp.CodeAnalysis.Semantics
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Base class representing a statement semantic.
|
/// Base class representing a statement semantic.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class BoundStatement : IStatement
|
public abstract partial class BoundStatement : IStatement
|
||||||
{
|
{
|
||||||
public virtual bool IsInvalid => false;
|
public virtual bool IsInvalid => false;
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ namespace Pchp.CodeAnalysis.Semantics
|
||||||
public abstract TResult Accept<TArgument, TResult>(OperationVisitor<TArgument, TResult> visitor, TArgument argument);
|
public abstract TResult Accept<TArgument, TResult>(OperationVisitor<TArgument, TResult> visitor, TArgument argument);
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class BoundEmptyStatement : BoundStatement
|
public sealed partial class BoundEmptyStatement : BoundStatement
|
||||||
{
|
{
|
||||||
public override OperationKind Kind => OperationKind.EmptyStatement;
|
public override OperationKind Kind => OperationKind.EmptyStatement;
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ namespace Pchp.CodeAnalysis.Semantics
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents an expression statement.
|
/// Represents an expression statement.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class BoundExpressionStatement : BoundStatement, IExpressionStatement
|
public sealed partial class BoundExpressionStatement : BoundStatement, IExpressionStatement
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Expression of the statement.
|
/// Expression of the statement.
|
|
@ -12,7 +12,7 @@ namespace Pchp.CodeAnalysis.Semantics.Graph
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents edge between to graph blocks.
|
/// Represents edge between to graph blocks.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class Edge : AstNode
|
public abstract partial class Edge : AstNode
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Target blocks.
|
/// Target blocks.
|
||||||
|
|
|
@ -37,13 +37,20 @@ namespace Pchp.CodeAnalysis.Semantics
|
||||||
|
|
||||||
BoundExpression BindExpression(AST.Expression expr) => BindExpression(expr, AccessType.Read);
|
BoundExpression BindExpression(AST.Expression expr) => BindExpression(expr, AccessType.Read);
|
||||||
|
|
||||||
|
ImmutableArray<BoundArgument> BindArguments(IEnumerable<AST.Expression> expressions)
|
||||||
|
{
|
||||||
|
return BindExpressions(expressions)
|
||||||
|
.Select(x => new BoundArgument(x))
|
||||||
|
.ToImmutableArray();
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
public BoundStatement BindStatement(AST.Statement stmt)
|
public BoundStatement BindStatement(AST.Statement stmt)
|
||||||
{
|
{
|
||||||
Debug.Assert(stmt != null);
|
Debug.Assert(stmt != null);
|
||||||
|
|
||||||
if (stmt is AST.EchoStmt) return new BoundExpressionStatement(new BoundEcho(BindExpressions(((AST.EchoStmt)stmt).Parameters)));
|
if (stmt is AST.EchoStmt) return new BoundExpressionStatement(new BoundEcho(BindArguments(((AST.EchoStmt)stmt).Parameters)));
|
||||||
if (stmt is AST.ExpressionStmt) return new BoundExpressionStatement(BindExpression(((AST.ExpressionStmt)stmt).Expression, AccessType.None));
|
if (stmt is AST.ExpressionStmt) return new BoundExpressionStatement(BindExpression(((AST.ExpressionStmt)stmt).Expression, AccessType.None));
|
||||||
|
|
||||||
throw new NotImplementedException(stmt.GetType().FullName);
|
throw new NotImplementedException(stmt.GetType().FullName);
|
||||||
|
@ -114,6 +121,7 @@ namespace Pchp.CodeAnalysis.Semantics
|
||||||
case AST.Operations.Mul: return BinaryOperationKind.OperatorMultiply;
|
case AST.Operations.Mul: return BinaryOperationKind.OperatorMultiply;
|
||||||
case AST.Operations.Div: return BinaryOperationKind.OperatorDivide;
|
case AST.Operations.Div: return BinaryOperationKind.OperatorDivide;
|
||||||
case AST.Operations.Mod: return BinaryOperationKind.OperatorRemainder; // %
|
case AST.Operations.Mod: return BinaryOperationKind.OperatorRemainder; // %
|
||||||
|
case AST.Operations.Pow: return BinaryOperationKind.ObjectPower; // **
|
||||||
|
|
||||||
// shift
|
// shift
|
||||||
case AST.Operations.ShiftLeft: return BinaryOperationKind.OperatorLeftShift; // <<
|
case AST.Operations.ShiftLeft: return BinaryOperationKind.OperatorLeftShift; // <<
|
||||||
|
@ -163,17 +171,17 @@ namespace Pchp.CodeAnalysis.Semantics
|
||||||
//
|
//
|
||||||
case AST.Operations.AssignAdd: return BinaryOperationKind.OperatorAdd;
|
case AST.Operations.AssignAdd: return BinaryOperationKind.OperatorAdd;
|
||||||
case AST.Operations.AssignSub: return BinaryOperationKind.OperatorSubtract;
|
case AST.Operations.AssignSub: return BinaryOperationKind.OperatorSubtract;
|
||||||
case AST.Operations.AssignMul:
|
case AST.Operations.AssignMul: return BinaryOperationKind.OperatorMultiply;
|
||||||
case AST.Operations.AssignDiv:
|
case AST.Operations.AssignDiv: return BinaryOperationKind.OperatorDivide;
|
||||||
case AST.Operations.AssignAnd:
|
case AST.Operations.AssignAnd: return BinaryOperationKind.OperatorAnd;
|
||||||
case AST.Operations.AssignOr:
|
case AST.Operations.AssignOr: return BinaryOperationKind.OperatorOr;
|
||||||
case AST.Operations.AssignXor:
|
case AST.Operations.AssignXor: return BinaryOperationKind.OperatorExclusiveOr;
|
||||||
case AST.Operations.AssignAppend:
|
case AST.Operations.AssignAppend: return BinaryOperationKind.StringConcatenation;
|
||||||
case AST.Operations.AssignPrepend:
|
//case AST.Operations.AssignPrepend:
|
||||||
case AST.Operations.AssignMod:
|
case AST.Operations.AssignMod: return BinaryOperationKind.OperatorRemainder; // %
|
||||||
case AST.Operations.AssignPow:
|
case AST.Operations.AssignPow: return BinaryOperationKind.ObjectPower; // **
|
||||||
case AST.Operations.AssignShiftLeft:
|
case AST.Operations.AssignShiftLeft: return BinaryOperationKind.OperatorLeftShift;
|
||||||
case AST.Operations.AssignShiftRight:
|
case AST.Operations.AssignShiftRight: return BinaryOperationKind.OperatorRightShift;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
|
|
Загрузка…
Ссылка в новой задаче