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.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();