This commit is contained in:
Jakub Míšek 2016-03-03 11:03:20 +01:00
Родитель 9392dae0a9
Коммит a3f9fca0d9
9 изменённых файлов: 137 добавлений и 49 удалений

Просмотреть файл

@ -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.FlowAnalysis;
using Pchp.CodeAnalysis.Symbols;
using Pchp.CodeAnalysis.Semantics.Graph;
namespace Pchp.CodeAnalysis.CodeGen
{
@ -44,10 +45,37 @@ namespace Pchp.CodeAnalysis.CodeGen
#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>
/// Emit cast from one type to another.
/// </summary>
internal void EmitCast(INamedTypeSymbol from, INamedTypeSymbol to)
public void EmitCast(INamedTypeSymbol from, INamedTypeSymbol to)
{
throw new NotImplementedException();
}

Просмотреть файл

@ -83,19 +83,14 @@ namespace Pchp.CodeAnalysis.CodeGen
// asyncDebugInfo = new Cci.AsyncMethodBodyDebugInfo(kickoffMethod, kickoffMethod.ReturnsVoid ? asyncCatchHandlerOffset : -1, asyncYieldPoints, asyncResumePoints);
//}
//else
//{
// codeGen.Generate();
//}
// DEBUG
builder.EmitNullConstant();
builder.EmitRet(false);
{
codeGen.Generate();
}
//
builder.Realize();
// DEBUG
//
var localVariables = builder.LocalSlotManager.LocalsInOrder();
if (localVariables.Length > 0xFFFE)

Просмотреть файл

@ -55,7 +55,9 @@
<ItemGroup>
<Compile Include="CodeGen\BoundVariable.cs" />
<Compile Include="CodeGen\CodeGenerator.cs" />
<Compile Include="CodeGen\BoundExpression.cs" />
<Compile Include="CodeGen\Places.cs" />
<Compile Include="CodeGen\BoundStatement.cs" />
<Compile Include="Compilation\SourceCompiler.cs" />
<Compile Include="Emitter\Model\FieldSymbolAdapter.cs" />
<Compile Include="FlowAnalysis\FlowContext.cs" />
@ -73,7 +75,7 @@
<Compile Include="FlowAnalysis\Visitors\LocalsWalker.cs" />
<Compile Include="FlowAnalysis\Worklist.cs" />
<Compile Include="Semantics\BoundVariable.cs" />
<Compile Include="Semantics\Expressions.cs" />
<Compile Include="Semantics\BoundExpression.cs" />
<Compile Include="Semantics\ExpressionsExtension.cs" />
<Compile Include="Semantics\Graph\BoundBlock.cs" />
<Compile Include="Semantics\Graph\BuilderVisitor.cs" />
@ -81,7 +83,7 @@
<Compile Include="Semantics\Graph\Edge.cs" />
<Compile Include="Semantics\Graph\GraphVisitor.cs" />
<Compile Include="Semantics\SemanticsBinder.cs" />
<Compile Include="Semantics\Statements.cs" />
<Compile Include="Semantics\BoundStatement.cs" />
<Compile Include="CodeGen\MethodGenerator.cs" />
<Compile Include="CommandLine\PhpCommandLineArguments.cs" />
<Compile Include="CommandLine\PhpCommandLineParser.cs" />

Просмотреть файл

@ -45,7 +45,7 @@ namespace Pchp.CodeAnalysis.Semantics
#region BoundExpression
public abstract class BoundExpression : IExpression
public abstract partial class BoundExpression : IExpression
{
public TypeRefMask TypeRefMask { get; set; } = default(TypeRefMask);
@ -70,26 +70,55 @@ namespace Pchp.CodeAnalysis.Semantics
#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>
/// Represents a function call.
/// </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> ArgumentsInSourceOrder
{
get
{
throw new NotImplementedException();
}
}
public ImmutableArray<IArgument> ArgumentsInSourceOrder => StaticCast<IArgument>.From(_arguments);
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;
@ -100,6 +129,12 @@ namespace Pchp.CodeAnalysis.Semantics
public IMethodSymbol TargetMethod { get; set; }
public BoundFunctionCall(ImmutableArray<BoundArgument> arguments)
{
Debug.Assert(!arguments.IsDefault);
_arguments = arguments;
}
public override void Accept(OperationVisitor visitor)
=> visitor.VisitInvocationExpression(this);
@ -111,11 +146,11 @@ namespace Pchp.CodeAnalysis.Semantics
#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
public class BoundLiteral : BoundExpression, ILiteralExpression
public partial class BoundLiteral : BoundExpression, ILiteralExpression
{
Optional<object> _value;
@ -149,7 +184,7 @@ namespace Pchp.CodeAnalysis.Semantics
#region BoundBinaryEx
public sealed class BoundBinaryEx : BoundExpression, IBinaryOperatorExpression
public sealed partial class BoundBinaryEx : BoundExpression, IBinaryOperatorExpression
{
public BinaryOperationKind BinaryOperationKind { get; private set; }
@ -181,7 +216,7 @@ namespace Pchp.CodeAnalysis.Semantics
#region BoundAssignEx, BoundCompoundAssignEx
public class BoundAssignEx : BoundExpression, IAssignmentExpression
public partial class BoundAssignEx : BoundExpression, IAssignmentExpression
{
public override OperationKind Kind => OperationKind.AssignmentExpression;
@ -202,7 +237,7 @@ namespace Pchp.CodeAnalysis.Semantics
=> visitor.VisitAssignmentExpression(this, argument);
}
public class BoundCompoundAssignEx : BoundAssignEx, ICompoundAssignmentExpression
public partial class BoundCompoundAssignEx : BoundAssignEx, ICompoundAssignmentExpression
{
public BinaryOperationKind BinaryKind { get; private set; }
@ -229,7 +264,7 @@ namespace Pchp.CodeAnalysis.Semantics
#region BoundReferenceExpression
public abstract class BoundReferenceExpression : BoundExpression, IReferenceExpression
public abstract partial class BoundReferenceExpression : BoundExpression, IReferenceExpression
{
}
@ -241,7 +276,7 @@ namespace Pchp.CodeAnalysis.Semantics
/// <summary>
/// A variable reference that can be read or written to.
/// </summary>
public class BoundVariableRef : BoundReferenceExpression, ILocalReferenceExpression
public partial class BoundVariableRef : BoundReferenceExpression, ILocalReferenceExpression
{
readonly string _name;
BoundVariable _variable;

Просмотреть файл

@ -14,7 +14,7 @@ namespace Pchp.CodeAnalysis.Semantics
/// <summary>
/// Base class representing a statement semantic.
/// </summary>
public abstract class BoundStatement : IStatement
public abstract partial class BoundStatement : IStatement
{
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 sealed class BoundEmptyStatement : BoundStatement
public sealed partial class BoundEmptyStatement : BoundStatement
{
public override OperationKind Kind => OperationKind.EmptyStatement;
@ -41,7 +41,7 @@ namespace Pchp.CodeAnalysis.Semantics
/// <summary>
/// Represents an expression statement.
/// </summary>
public sealed class BoundExpressionStatement : BoundStatement, IExpressionStatement
public sealed partial class BoundExpressionStatement : BoundStatement, IExpressionStatement
{
/// <summary>
/// Expression of the statement.

Просмотреть файл

@ -12,7 +12,7 @@ namespace Pchp.CodeAnalysis.Semantics.Graph
/// <summary>
/// Represents edge between to graph blocks.
/// </summary>
public abstract class Edge : AstNode
public abstract partial class Edge : AstNode
{
/// <summary>
/// Target blocks.

Просмотреть файл

@ -37,13 +37,20 @@ namespace Pchp.CodeAnalysis.Semantics
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
public BoundStatement BindStatement(AST.Statement stmt)
{
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));
throw new NotImplementedException(stmt.GetType().FullName);
@ -114,6 +121,7 @@ namespace Pchp.CodeAnalysis.Semantics
case AST.Operations.Mul: return BinaryOperationKind.OperatorMultiply;
case AST.Operations.Div: return BinaryOperationKind.OperatorDivide;
case AST.Operations.Mod: return BinaryOperationKind.OperatorRemainder; // %
case AST.Operations.Pow: return BinaryOperationKind.ObjectPower; // **
// shift
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.AssignSub: return BinaryOperationKind.OperatorSubtract;
case AST.Operations.AssignMul:
case AST.Operations.AssignDiv:
case AST.Operations.AssignAnd:
case AST.Operations.AssignOr:
case AST.Operations.AssignXor:
case AST.Operations.AssignAppend:
case AST.Operations.AssignPrepend:
case AST.Operations.AssignMod:
case AST.Operations.AssignPow:
case AST.Operations.AssignShiftLeft:
case AST.Operations.AssignShiftRight:
case AST.Operations.AssignMul: return BinaryOperationKind.OperatorMultiply;
case AST.Operations.AssignDiv: return BinaryOperationKind.OperatorDivide;
case AST.Operations.AssignAnd: return BinaryOperationKind.OperatorAnd;
case AST.Operations.AssignOr: return BinaryOperationKind.OperatorOr;
case AST.Operations.AssignXor: return BinaryOperationKind.OperatorExclusiveOr;
case AST.Operations.AssignAppend: return BinaryOperationKind.StringConcatenation;
//case AST.Operations.AssignPrepend:
case AST.Operations.AssignMod: return BinaryOperationKind.OperatorRemainder; // %
case AST.Operations.AssignPow: return BinaryOperationKind.ObjectPower; // **
case AST.Operations.AssignShiftLeft: return BinaryOperationKind.OperatorLeftShift;
case AST.Operations.AssignShiftRight: return BinaryOperationKind.OperatorRightShift;
default:
throw new NotImplementedException();