public void ExecuteAction() { IExpression exp = Parser.Parse(PropertyExpression); if (exp is PropertyAccessExpression) { IExpression expVal = Parser.Parse(ValueExpression); expVal.CheckSemantics(Parser.ParsingContext); PropertyAccessExpression paexp = (PropertyAccessExpression)exp; paexp.CheckSemantics(Parser.ParsingContext); if (paexp.ExpressionType != expVal.ExpressionType) { throw new Exception.ActionExecutionException("Tipos incompatíveis"); } paexp.Property.SetValue(paexp.ObjectExpression.Eval(), expVal.Eval(), null); } else { throw new Exception.ActionExecutionException("Não é uma propriedade"); } }
private EntityExpression GetParentExpression(MemberExpression expr, out string memberName, out IType nhibernateType) { memberName = null; nhibernateType = null; CollectionAccessExpression collectionExpr = expr.Expression as CollectionAccessExpression; if (collectionExpr != null) { return(null); } PropertyAccessExpression propExpr = expr.Expression as PropertyAccessExpression; if (propExpr != null) { memberName = propExpr.Name + "." + expr.Member.Name; nhibernateType = propExpr.Expression.MetaData.GetPropertyType(memberName); return(propExpr.Expression); } EntityExpression entityExpr = expr.Expression as EntityExpression; if (entityExpr != null) { memberName = expr.Member.Name; nhibernateType = entityExpr.MetaData.GetPropertyType(memberName); return(entityExpr); } return(null); }
protected override Expression VisitPropertyAccess(PropertyAccessExpression expr) { string memberName = MemberNameVisitor.GetMemberName(_rootCriteria, expr); _projections.Add(NHProjections.Property(memberName)); return(expr); }
public void TwoStringList() { var node = new PropertyAccessExpression(new List <string> { "first", "second" }); Assert.Equal("first.second", node.GetFormattedText()); }
public void FourStringList() { var node = new PropertyAccessExpression(new List <string> { "first", "second", "third", "fourth" }); Assert.Equal("first.second.third.fourth", node.GetFormattedText()); }
public virtual Expression VisitPropertyAccessExpression(PropertyAccessExpression expression) { Check.NotNull(expression, "expression"); _sql.Append(expression.Property.StorageName); return(expression); }
protected virtual Expression VisitPropertyAccess(PropertyAccessExpression expr) { EntityExpression e = (EntityExpression)Visit(expr.Expression); if (e != expr.Expression) { return(new PropertyAccessExpression(expr.Name, expr.Type, expr.NHibernateType, e)); } return(expr); }
protected override Expression VisitPropertyAccess(PropertyAccessExpression expr) { expr = (PropertyAccessExpression)base.VisitPropertyAccess(expr); memberNameBuilder.Append(expr.Name + "."); currentExpression = expr; isQueringEntity = false; return(expr); }
protected override Expression VisitPropertyAccess(PropertyAccessExpression expr) { if (expr.Type == typeof(bool)) { string name = MemberNameVisitor.GetMemberName(rootCriteria, expr); CurrentCriterions.Add(Restrictions.Eq(name, true)); } return(expr); }
public CSharpSyntaxNode Convert(Identifier node) { string text = node.Text; if (IdentifierMappings.ContainsKey(text)) { text = IdentifierMappings[text]; } if (text == "length" && node.Parent.Kind == NodeKind.PropertyAccessExpression) { PropertyAccessExpression parent = node.Parent as PropertyAccessExpression; Node type = TypeHelper.GetNodeType(parent.Expression); if (type != null) { type = TypeHelper.TrimNullUnionType(type); if (TypeHelper.IsStringType(type)) { text = "Length"; } else if (TypeHelper.IsArrayType(type)) { if (type.Parent != null && type.Parent.Kind == NodeKind.Parameter && (type.Parent as Parameter).IsVariable) { text = "Length"; } else { text = "Count"; } } } } NameSyntax csNameSyntax = null; List <Node> typeArguments = node.Parent == null ? null : node.Parent.GetValue("TypeArguments") as List <Node>; List <Node> arguments = node.Parent == null ? null : node.Parent.GetValue("Arguments") as List <Node>; if (typeArguments != null && typeArguments.Count > 0 && (arguments == null || !arguments.Contains(node))) //not in arguments { csNameSyntax = SyntaxFactory .GenericName(text) .AddTypeArgumentListArguments(typeArguments.ToCsNodes <TypeSyntax>()); } else { csNameSyntax = SyntaxFactory.IdentifierName(text); } // return(this.As(csNameSyntax, node.As)); }
protected Expression transformPA(PropertyAccessExpression expr) { if (expr.object_ is ClassReference classRef) { return(this.getStaticRef(classRef.decl, expr.propertyName)); } if (expr.object_ is StaticThisReference statThisRef) { return(this.getStaticRef(statThisRef.cls, expr.propertyName)); } expr.object_ = this.main.runPluginsOn(expr.object_); if (expr.object_ is ThisReference thisRef) { return(this.getInstanceRef(thisRef.cls, expr.propertyName, thisRef)); } var type = expr.object_.getType(); if (type is ClassType classType) { return(this.getInstanceRef(classType.decl, expr.propertyName, expr.object_)); } else if (type is InterfaceType intType) { var ref_ = this.getInterfaceRef(intType.decl, expr.propertyName, expr.object_); if (ref_ == null) { this.errorMan.throw_($"Could not resolve instance member access of a interface: {intType.repr()}::{expr.propertyName}"); } return(ref_); } else if (type == null) { this.errorMan.throw_($"Type was not inferred yet (prop=\"{expr.propertyName}\")"); } else if (type is AnyType) { //this.errorMan.throw(`Object has any type (prop="${expr.propertyName}")`); expr.setActualType(AnyType.instance); } else { this.errorMan.throw_($"Expected class as variable type, but got: {type.repr()} (prop=\"{expr.propertyName}\")"); } return(expr); }
private bool WithInStaticMethod(PropertyAccessExpression node) { Node parent = node.Parent; while (parent != null) { if (parent.Kind == NodeKind.MethodDeclaration || parent.Kind == NodeKind.ClassDeclaration) { break; } parent = parent.Parent; } return(!(parent is MethodDeclaration method) ? false : method.IsStatic); }
public CSharpSyntaxNode Convert(PropertyAccessExpression node) { Node parent = node.Parent; if (parent != null && parent.Kind == NodeKind.EnumMember && node.Text.Trim() == "Number.MAX_VALUE") { return(SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.IntKeyword)), SyntaxFactory.IdentifierName("MaxValue"))); } SimpleNameSyntax csName = null; if (parent != null) { Node expression = parent.GetValue("Expression") as Node; List <Node> typeArguments = parent.GetValue("TypeArguments") as List <Node>; if (expression != null && expression == node && typeArguments != null && typeArguments.Count > 0) { csName = SyntaxFactory .GenericName(node.Name.Text) .AddTypeArgumentListArguments(typeArguments.ToCsNodes <TypeSyntax>()); } } if (csName == null) { csName = node.Name.ToCsNode <SimpleNameSyntax>(); } // omit this if (node.Expression.Kind == NodeKind.ThisKeyword && WithInStaticMethod(node)) { return(csName); } // omit names(dv. core.) List <string> omittedNames = this.Context.Config.OmittedQualifiedNames; if (omittedNames.Count > 0 && omittedNames.Contains(node.Expression.Text.Trim())) { return(csName); } // MemberAccessExpressionSyntax accessExprSyntax = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, node.Expression.ToCsNode <ExpressionSyntax>(), csName); return(this.As(accessExprSyntax, node.As)); }
private static IEnumerable <JsonElement> ExecuteInternal(PropertyAccessExpression expr, JsonElement e) { if (expr.ChildProperties) { return(PropertyAccessor.GetChildPropertyValues(e)); } else if (expr.RecursiveProperties) { return(PropertyAccessor.GetRecursiveProperties(e)); } else if (expr.Properties != null && expr.Properties.Any()) { return(PropertyAccessor.GetPropertyValueFromChain(e, expr.Properties)); } throw new InvalidOperationException($"PropertyAccessExpression"); }
private string AssociationPathForEntity(MemberExpression expr) { PropertyAccessExpression propExpr = expr.Expression as PropertyAccessExpression; if (propExpr != null) { return(propExpr.Name + "." + expr.Member.Name); } EntityExpression entityExpr = expr.Expression as EntityExpression; if (entityExpr != null && entityExpr.Expression != null) { return(entityExpr.Alias + "." + expr.Member.Name); } return(expr.Member.Name); }
private void NormalizeInstanceOf(BinaryExpression instanceOf) { Node leftNode = instanceOf.Left; Node leftNodeType = TypeHelper.GetNodeType(leftNode); if (leftNodeType != null && TypeHelper.ToShortName(leftNodeType.Text) == "DataValueType") { PropertyAccessExpression newLeft = NodeHelper.CreateNode(NodeKind.PropertyAccessExpression) as PropertyAccessExpression; newLeft.Parent = leftNode.Parent; leftNode.Parent = newLeft; newLeft.SetExpression(leftNode); newLeft.SetName(NodeHelper.CreateNode(NodeKind.Identifier, "Value")); instanceOf.SetLeft(newLeft); return; } NodeKind variableKind = instanceOf.Left.Kind; string variableName = instanceOf.Left.Text.Trim(); string typeName = instanceOf.Right.Text; List <Node> asNodes = new List <Node>(); Node parent = instanceOf.Parent; while (parent != null) { if (parent.Kind == NodeKind.Block || parent.Kind == NodeKind.CaseBlock) { break; } else if (parent.Kind == NodeKind.IfStatement) { List <Node> multiInstanceOf = (parent as IfStatement).Expression.DescendantsAndSelf(n => { if (n.Kind == NodeKind.BinaryExpression && n != instanceOf) { BinaryExpression binary = n as BinaryExpression; return(binary.OperatorToken.Kind == NodeKind.InstanceOfKeyword && binary.Left.Text.Trim() == variableName); } return(false); }); if (multiInstanceOf.Count == 0) { asNodes.AddRange((parent as IfStatement).ThenStatement.Descendants(n => n.Kind == variableKind && n.Text.Trim() == variableName)); } break; } else if (parent.Kind == NodeKind.BinaryExpression) { BinaryExpression binaryExpr = parent as BinaryExpression; bool instanceOfIsLeftNode = (binaryExpr.Left.DescendantsAndSelfOnce(n => n == instanceOf).Count > 0); if (instanceOfIsLeftNode) { asNodes.AddRange(binaryExpr.Right.Descendants(n => { bool isInInstanceOf = (n.Parent.Kind == NodeKind.BinaryExpression && (n.Parent as BinaryExpression).OperatorToken.Kind == NodeKind.InstanceOfKeyword); return(n.Kind == variableKind && n.Text.Trim() == variableName && !isInInstanceOf); })); } } parent = parent.Parent; } foreach (Node asNode in asNodes) { switch (asNode.Kind) { case NodeKind.Identifier: if (asNode.Parent.Kind == NodeKind.PropertyAccessExpression) { if (asNode == (asNode.Parent as PropertyAccessExpression).Expression) { (asNode as Identifier).As = typeName; } } else { (asNode as Identifier).As = typeName; } break; case NodeKind.PropertyAccessExpression: if (!(asNode.Parent.Kind == NodeKind.BinaryExpression && (asNode.Parent as BinaryExpression).Left == asNode)) { (asNode as PropertyAccessExpression).As = typeName; } break; default: break; } } }
internal virtual void VisitPropertyAccessExpr(PropertyAccessExpression prop) { }
protected override Expression VisitPropertyAccess(PropertyAccessExpression expr) { Type = BinaryCriterionType.Property; return(expr); }
public Expression parse(int precedence = 0, bool required = true) { this.reader.skipWhitespace(); var leftStart = this.reader.offset; var left = this.parseLeft(required); if (left == null) { return(null); } this.addNode(left, leftStart); while (true) { if (this.hooks != null) { var parsed = this.hooks.infixPrehook(left); if (parsed != null) { left = parsed; this.addNode(left, leftStart); continue; } } var op = this.parseOperator(); if (op == null || op.precedence <= precedence) { break; } this.reader.expectToken(op.text); var opText = this.config.aliases.hasKey(op.text) ? this.config.aliases.get(op.text) : op.text; if (op.isBinary) { var right = this.parse(op.isRightAssoc ? op.precedence - 1 : op.precedence); left = new BinaryExpression(left, opText, right); } else if (op.isPostfix) { left = new UnaryExpression(UnaryType.Postfix, opText, left); } else if (op.text == "?") { var whenTrue = this.parse(); this.reader.expectToken(":"); var whenFalse = this.parse(op.precedence - 1); left = new ConditionalExpression(left, whenTrue, whenFalse); } else if (op.text == "(") { var args = this.parseCallArguments(); left = new UnresolvedCallExpression(left, new IType[0], args); } else if (op.text == "[") { var elementExpr = this.parse(); this.reader.expectToken("]"); left = new ElementAccessExpression(left, elementExpr); } else if (this.config.propertyAccessOps.includes(op.text)) { var prop = this.reader.expectIdentifier("expected identifier as property name"); left = new PropertyAccessExpression(left, prop); } else { this.reader.fail($"parsing '{op.text}' is not yet implemented"); } this.addNode(left, leftStart); } if (left is ParenthesizedExpression parExpr && parExpr.expression is Identifier ident) { var expr = this.parse(0, false); if (expr != null) { return(new CastExpression(new UnresolvedType(ident.text, new IType[0]), expr)); } } return(left); }
protected virtual Expression VisitPropertyAccess(PropertyAccessExpression node) => base.VisitExtension(node);
public void TwoStringParams() { var node = new PropertyAccessExpression("first", "second"); Assert.Equal("first.second", node.GetFormattedText()); }
protected override Expression VisitPropertyAccess(PropertyAccessExpression expr) { Type = BinaryCriterionType.Property; Name = MemberNameVisitor.GetMemberName(rootCriteria, expr); return(expr); }
public void BlockProcess(DecompileContext context, Block block, Dictionary <int, Expression> exps) { if (block.Statements != null) { return; } if (block.From.Count > 1) { //get from.Output && from.Def var commonInput = block.From.Select(b => b.Output).Union(block.From.Select(b => b.Def)).GetIntersection(); commonInput.IntersectWith(block.Input); //flag can be phi if (commonInput.Count > 0) { foreach (var inSlot in commonInput) { //Generate Phi var phi = new PhiExpression(inSlot); //From must be sorted since we need first condition if (block.From[0].Statements?.Last() is ConditionExpression condition) { phi.Condition = condition; //var thenBlock = context.BlockTable[condition.JumpTo]; var elseBlock = context.BlockTable[condition.ElseTo]; //phi.ThenBranch = context.BlockFinalStates[trueBlock][inSlot]; phi.ThenBranch = context.BlockFinalStates[block.From[0]] [inSlot]; //if jump, use the state from the jump-from block phi.ElseBranch = context.BlockFinalStates[elseBlock][inSlot]; //Next: Merge condition: if (v1) then v1 else v2 => v1 || v2 (infer v1 is bool) if (phi.ThenBranch != phi.ElseBranch) { exps[inSlot] = phi; } } } } } Expression retExp = null; var ex = new Dictionary <int, Expression>(exps); var flag = ex.ContainsKey(Const.FlagReg) ? ex[Const.FlagReg] : null; var expList = new List <IAstNode>(); block.Statements = expList; InstructionData insData = null; for (var i = 0; i < block.Instructions.Count; i++) { ex[0] = Void; var ins = block.Instructions[i]; insData = block.InstructionDatas[i]; switch (ins.OpCode) { case OpCode.NOP: break; case OpCode.CONST: { var data = (OperandData)ins.Data; var constExp = new ConstantExpression(data.Variant); ex[ins.GetRegisterSlot(0)] = constExp; } break; case OpCode.CL: { ex[ins.GetRegisterSlot(0)] = null; } break; case OpCode.CCL: break; case OpCode.CEQ: case OpCode.CDEQ: case OpCode.CLT: case OpCode.CGT: { var left = ex[ins.GetRegisterSlot(0)]; var right = ex[ins.GetRegisterSlot(1)]; BinaryOp op = BinaryOp.Unknown; switch (ins.OpCode) { case OpCode.CEQ: op = BinaryOp.Equal; break; case OpCode.CDEQ: op = BinaryOp.Congruent; break; case OpCode.CLT: op = BinaryOp.LessThan; break; case OpCode.CGT: op = BinaryOp.GreaterThan; break; } var b = new BinaryExpression(left, right, op); flag = b; } break; case OpCode.SETF: case OpCode.SETNF: { var dst = ins.GetRegisterSlot(0); switch (ins.OpCode) { case OpCode.SETF: ex[dst] = flag; break; case OpCode.SETNF: ex[dst] = flag.Invert(); break; } } break; case OpCode.TT: { flag = ex[ins.GetRegisterSlot(0)]; } break; case OpCode.TF: { flag = ex[ins.GetRegisterSlot(0)].Invert(); } break; case OpCode.NF: { flag = flag.Invert(); } break; case OpCode.JF: case OpCode.JNF: { bool jmpFlag = ins.OpCode == OpCode.JF; expList.Add(new ConditionExpression(flag, jmpFlag) { JumpTo = ((JumpData)ins.Data).Goto.Line, ElseTo = ins.Line + 1 }); } break; case OpCode.JMP: { expList.Add(new GotoExpression { JumpTo = ((JumpData)ins.Data).Goto.Line }); } break; case OpCode.CHS: case OpCode.INT: case OpCode.REAL: case OpCode.STR: case OpCode.NUM: case OpCode.OCTET: case OpCode.LNOT: case OpCode.INC: case OpCode.DEC: case OpCode.BNOT: case OpCode.TYPEOF: case OpCode.INV: { var dstSlot = ins.GetRegisterSlot(0); var dst = ex[dstSlot]; var op = UnaryOp.Unknown; switch (ins.OpCode) { case OpCode.INC: op = UnaryOp.Inc; break; case OpCode.DEC: op = UnaryOp.Dec; break; case OpCode.CHS: op = UnaryOp.InvertSign; break; case OpCode.INT: op = UnaryOp.ToInt; break; case OpCode.REAL: op = UnaryOp.ToReal; break; case OpCode.STR: op = UnaryOp.ToString; break; case OpCode.NUM: op = UnaryOp.ToNumber; break; case OpCode.BNOT: op = UnaryOp.BitNot; break; case OpCode.OCTET: op = UnaryOp.ToByteArray; break; case OpCode.LNOT: op = UnaryOp.Not; break; case OpCode.TYPEOF: op = UnaryOp.TypeOf; break; case OpCode.INV: op = UnaryOp.Invalidate; break; } var u = new UnaryExpression(dst, op); //ex[dstSlot] = u; expList.Add(u); } break; case OpCode.INCPD: case OpCode.DECPD: case OpCode.TYPEOFD: { var res = ins.GetRegisterSlot(0); var obj = ins.GetRegisterSlot(1); var name = ins.Data.AsString(); var op = UnaryOp.Unknown; switch (ins.OpCode) { case OpCode.INCPI: op = UnaryOp.Inc; break; case OpCode.DECPI: op = UnaryOp.Dec; break; case OpCode.TYPEOFD: op = UnaryOp.TypeOf; break; } //var u = new UnaryExpression(new IdentifierExpression(name), op) {Instance = ex[obj]}; var u = new UnaryExpression(new IdentifierExpression(name) { Instance = ex[obj] }, op); if (res != 0) //copy to %res { ex[res] = u; } expList.Add(u); } break; case OpCode.INCPI: case OpCode.DECPI: case OpCode.TYPEOFI: { var res = ins.GetRegisterSlot(0); var obj = ins.GetRegisterSlot(1); var name = ins.GetRegisterSlot(2); var op = UnaryOp.Unknown; switch (ins.OpCode) { case OpCode.INCPI: op = UnaryOp.Inc; break; case OpCode.DECPI: op = UnaryOp.Dec; break; case OpCode.TYPEOFI: op = UnaryOp.TypeOf; break; } var u = new UnaryExpression(new PropertyAccessExpression(ex[name], ex[obj]), op); if (res != 0) //copy to %res { ex[res] = u; } expList.Add(u); } break; case OpCode.INCP: case OpCode.DECP: break; case OpCode.LORP: break; case OpCode.LANDP: break; case OpCode.BORP: break; case OpCode.BXORP: break; case OpCode.BANDP: break; case OpCode.SARP: break; case OpCode.SALP: break; case OpCode.SRP: break; case OpCode.CP: { var dstSlot = ins.GetRegisterSlot(0); var srcSlot = ins.GetRegisterSlot(1); Expression src; if (ex.ContainsKey(srcSlot)) { src = ex[srcSlot]; } else { src = new LocalExpression(context.Object, srcSlot); } Expression dst = null; if (ex.ContainsKey(dstSlot)) { //dst = ex[dstSlot]; ex[dstSlot] = src; } else if (dstSlot < -2) { var l = new LocalExpression(context.Object, dstSlot); //if (!l.IsParameter) //{ // expList.Add(l); //} dst = l; ex[dstSlot] = l; //assignment -> statements, local -> expressions BinaryExpression b = new BinaryExpression(dst, src, BinaryOp.Assign) { IsDeclaration = true }; //ex[dstSlot] = b; expList.Add(b); } else if (dstSlot != 0) { ex[dstSlot] = src; } } break; //Binary Operation case OpCode.ADD: case OpCode.SUB: case OpCode.MOD: case OpCode.DIV: case OpCode.IDIV: case OpCode.MUL: case OpCode.BAND: case OpCode.BOR: case OpCode.BXOR: case OpCode.LAND: case OpCode.LOR: case OpCode.SAR: case OpCode.SAL: case OpCode.SR: case OpCode.CHKINS: { var dstSlot = ins.GetRegisterSlot(0); var srcSlot = ins.GetRegisterSlot(1); var store = false; //Set to Expression var declare = false; //Is declaration Expression dst = null; if (ex.ContainsKey(dstSlot)) { dst = ex[dstSlot]; } else if (dstSlot < -2) { var l = new LocalExpression(context.Object, dstSlot); //if (!l.IsParameter) //{ // expList.Add(l); //} dst = l; ex[dstSlot] = l; store = false; declare = true; } Expression src; if (ex.ContainsKey(srcSlot)) { src = ex[srcSlot]; } else { src = new LocalExpression(context.Object, srcSlot); } var op = BinaryOp.Unknown; switch (ins.OpCode) { case OpCode.ADD: op = BinaryOp.Add; break; case OpCode.SUB: op = BinaryOp.Sub; break; case OpCode.MOD: op = BinaryOp.Mod; break; case OpCode.DIV: op = BinaryOp.Div; break; case OpCode.IDIV: op = BinaryOp.Idiv; break; case OpCode.MUL: op = BinaryOp.Mul; break; case OpCode.BAND: op = BinaryOp.BitAnd; break; case OpCode.BOR: op = BinaryOp.BitOr; break; case OpCode.BXOR: op = BinaryOp.BitXor; break; case OpCode.LAND: op = BinaryOp.LogicAnd; break; case OpCode.LOR: op = BinaryOp.LogicOr; break; case OpCode.SAR: op = BinaryOp.NumberShiftRight; break; case OpCode.SAL: op = BinaryOp.NumberShiftLeft; break; case OpCode.SR: op = BinaryOp.BitShiftRight; break; //case OpCode.CP: //moved! // op = BinaryOp.Assign; // push = true; //break; case OpCode.CHKINS: op = BinaryOp.InstanceOf; break; } BinaryExpression b = new BinaryExpression(dst, src, op) { IsDeclaration = declare }; if (store) { ex[dstSlot] = b; } expList.Add(b); } break; case OpCode.ADDPD: case OpCode.SUBPD: case OpCode.MODPD: case OpCode.DIVPD: case OpCode.IDIVPD: case OpCode.MULPD: case OpCode.BANDPD: case OpCode.BORPD: case OpCode.BXORPD: case OpCode.LANDPD: case OpCode.LORPD: case OpCode.SARPD: case OpCode.SALPD: case OpCode.SRPD: { var res = ins.GetRegisterSlot(0); var obj = ins.GetRegisterSlot(1); var name = ins.Data.AsString(); var op = BinaryOp.Unknown; var src = ex[ins.GetRegisterSlot(3)]; switch (ins.OpCode) { case OpCode.ADDPD: op = BinaryOp.Add; break; case OpCode.SUBPD: op = BinaryOp.Sub; break; case OpCode.MODPD: op = BinaryOp.Mod; break; case OpCode.DIVPD: op = BinaryOp.Div; break; case OpCode.IDIVPD: op = BinaryOp.Idiv; break; case OpCode.MULPD: op = BinaryOp.Mul; break; case OpCode.BANDPD: op = BinaryOp.BitAnd; break; case OpCode.BORPD: op = BinaryOp.BitOr; break; case OpCode.BXORPD: op = BinaryOp.BitXor; break; case OpCode.LANDPD: op = BinaryOp.LogicAnd; break; case OpCode.LORPD: op = BinaryOp.LogicOr; break; case OpCode.SARPD: op = BinaryOp.NumberShiftRight; break; case OpCode.SALPD: op = BinaryOp.NumberShiftLeft; break; case OpCode.SRPD: op = BinaryOp.BitShiftRight; break; } BinaryExpression b = new BinaryExpression(new IdentifierExpression(name) { Instance = ex[obj] }, src, op); if (res != 0) { ex[res] = b; } expList.Add(b); } break; case OpCode.ADDPI: case OpCode.SUBPI: case OpCode.MODPI: case OpCode.DIVPI: case OpCode.IDIVPI: case OpCode.MULPI: case OpCode.BANDPI: case OpCode.BORPI: case OpCode.BXORPI: case OpCode.LANDPI: case OpCode.LORPI: case OpCode.SARPI: case OpCode.SALPI: case OpCode.SRPI: { var res = ins.GetRegisterSlot(0); var obj = ins.GetRegisterSlot(1); var name = ins.GetRegisterSlot(2); var op = BinaryOp.Unknown; var src = ex[ins.GetRegisterSlot(3)]; switch (ins.OpCode) { case OpCode.ADDPI: op = BinaryOp.Add; break; case OpCode.SUBPI: op = BinaryOp.Sub; break; case OpCode.MODPI: op = BinaryOp.Mod; break; case OpCode.DIVPI: op = BinaryOp.Div; break; case OpCode.IDIVPI: op = BinaryOp.Idiv; break; case OpCode.MULPI: op = BinaryOp.Mul; break; case OpCode.BANDPI: op = BinaryOp.BitAnd; break; case OpCode.BORPI: op = BinaryOp.BitOr; break; case OpCode.BXORPI: op = BinaryOp.BitXor; break; case OpCode.LANDPI: op = BinaryOp.LogicAnd; break; case OpCode.LORPI: op = BinaryOp.LogicOr; break; case OpCode.SARPI: op = BinaryOp.NumberShiftRight; break; case OpCode.SALPI: op = BinaryOp.NumberShiftLeft; break; case OpCode.SRPI: op = BinaryOp.BitShiftRight; break; } BinaryExpression b = new BinaryExpression(new PropertyAccessExpression(ex[name], ex[obj]), src, op); if (res != 0) { ex[res] = b; } expList.Add(b); } break; case OpCode.ADDP: break; case OpCode.SUBP: break; case OpCode.MODP: break; case OpCode.DIVP: break; case OpCode.IDIVP: break; case OpCode.MULP: break; case OpCode.EVAL: break; case OpCode.EEXP: break; case OpCode.ASC: break; case OpCode.CHR: break; case OpCode.CHKINV: break; //Invoke case OpCode.CALL: { var call = new InvokeExpression(((OperandData)ins.Data).Variant as TjsCodeObject); var dst = ins.GetRegisterSlot(0); call.Instance = null; var paramCount = ins.GetRegisterSlot(2); if (paramCount == -1) { //... //do nothing } else { for (int j = 0; j < paramCount; j++) { var pSlot = ins.GetRegisterSlot(3 + j); call.Parameters.Add(ex[pSlot]); } } ex[dst] = call; //if (dst == 0) //just execute and discard result //{ // expList.Add(call); //} expList.Add(call); } break; case OpCode.CALLD: { var callMethodName = ins.Data.AsString(); var call = new InvokeExpression(callMethodName); var dst = ins.GetRegisterSlot(0); var callerSlot = ins.GetRegisterSlot(1); call.Instance = ex[callerSlot]; var paramCount = ins.GetRegisterSlot(3); if (paramCount == -1) { //... //do nothing } else { for (int j = 0; j < paramCount; j++) { var pSlot = ins.GetRegisterSlot(4 + j); ex[pSlot].Parent = call; call.Parameters.Add(ex[pSlot]); } } ex[dst] = call; if (dst == 0) //just execute and discard result { //Handle RegExp()._compile("//g/[^A-Za-z]") if (callMethodName == Const.RegExpCompile) { if (call.Instance is InvokeExpression invoke && invoke.Method == Const.RegExp) { call.InvokeType = InvokeType.RegExpCompile; ex[callerSlot] = call; break; } } expList.Add(call); } } break; case OpCode.CALLI: { //InvokeExpression call = null; //var operand = ((OperandData) ins.Data).Variant; //if (operand is TjsString str) //{ // call = new InvokeExpression(str.StringValue); //} //else //{ // call = new InvokeExpression(operand as TjsCodeObject); //} InvokeExpression call = new InvokeExpression(ex[ins.GetRegisterSlot(2)]); var dst = ins.GetRegisterSlot(0); var callerSlot = ins.GetRegisterSlot(1); call.Instance = ex[callerSlot]; var paramCount = ins.GetRegisterSlot(3); if (paramCount == -1) { //... //do nothing } else { for (int j = 0; j < paramCount; j++) { var pSlot = ins.GetRegisterSlot(4 + j); ex[pSlot].Parent = call; call.Parameters.Add(ex[pSlot]); } } ex[dst] = call; //if (dst == 0) //just execute and discard result //{ // expList.Add(call); //} expList.Add(call); } break; case OpCode.NEW: { InvokeExpression call = new InvokeExpression(ex[ins.GetRegisterSlot(1)]) { InvokeType = InvokeType.Ctor }; var dst = ins.GetRegisterSlot(0); call.Instance = null; var paramCount = ins.GetRegisterSlot(2); if (paramCount == -1) { //... //do nothing } else { for (int j = 0; j < paramCount; j++) { var pSlot = ins.GetRegisterSlot(3 + j); ex[pSlot].Parent = call; call.Parameters.Add(ex[pSlot]); } } ex[dst] = call; //if (dst == 0) //just execute and discard result //{ // expList.Add(call); //} expList.Add(call); } break; case OpCode.GPD: case OpCode.GPDS: { var dst = ins.GetRegisterSlot(0); var slot = ins.GetRegisterSlot(1); var instance = ex[slot]; var name = ins.Data.AsString(); var newId = new IdentifierExpression(name) { Instance = instance }; ex[dst] = newId; } break; case OpCode.GPI: case OpCode.GPIS: { var dst = ins.GetRegisterSlot(0); var obj = ins.GetRegisterSlot(1); var name = ins.GetRegisterSlot(2); PropertyAccessExpression p = new PropertyAccessExpression(ex[name], ex[obj]); ex[dst] = p; } break; case OpCode.SPI: case OpCode.SPIE: case OpCode.SPIS: { var obj = ins.GetRegisterSlot(0); var name = ins.GetRegisterSlot(1); var src = ins.GetRegisterSlot(2); BinaryExpression b = new BinaryExpression(new PropertyAccessExpression(ex[name], ex[obj]), ex[src], BinaryOp.Assign); expList.Add(b); //there is no other way to find this expression } break; //Set case OpCode.SPD: case OpCode.SPDE: case OpCode.SPDEH: case OpCode.SPDS: { var left = new IdentifierExpression(ins.Data.AsString()) { Instance = ex[ins.GetRegisterSlot(0)] }; var right = ex[ins.GetRegisterSlot(2)]; BinaryExpression b = new BinaryExpression(left, right, BinaryOp.Assign); //check declare if (context.Object.ContextType == TjsContextType.TopLevel) { if (!context.RegisteredMembers.ContainsKey(left.Name)) { b.IsDeclaration = true; var stub = new TjsStub(); if (right is ConstantExpression con) //TODO: better type check { stub.Type = con.DataType; } context.RegisteredMembers[left.Name] = stub; } } expList.Add(b); } break; case OpCode.SETP: { } break; case OpCode.GETP: { } break; //Delete case OpCode.DELD: DeleteExpression d = new DeleteExpression(ins.Data.AsString()); d.Instance = ex[ins.GetRegisterSlot(1)]; expList.Add(d); break; case OpCode.DELI: DeleteExpression d2 = new DeleteExpression(ex[ins.GetRegisterSlot(2)]); d2.Instance = ex[ins.GetRegisterSlot(1)]; //Check declare if (d2.Instance is IdentifierExpression toDel) { if (context.RegisteredMembers.ContainsKey(toDel.Name)) { context.RegisteredMembers.Remove(toDel.Name); } } expList.Add(d2); break; case OpCode.SRV: { var srv = ins.GetRegisterSlot(0); retExp = srv == 0 ? null : ex[srv]; } break; case OpCode.RET: { expList.Add(new ReturnExpression(retExp)); } break; case OpCode.ENTRY: break; case OpCode.EXTRY: break; case OpCode.THROW: { var th = new ThrowExpression(ex[ins.GetRegisterSlot(0)]); expList.Add(th); } break; case OpCode.CHGTHIS: break; case OpCode.GLOBAL: { ex[ins.GetRegisterSlot(0)] = Global; } break; case OpCode.ADDCI: break; case OpCode.REGMEMBER: break; case OpCode.DEBUGGER: break; case OpCode.LAST: break; case OpCode.PreDec: break; case OpCode.PostInc: break; case OpCode.PostDec: break; case OpCode.Delete: break; case OpCode.FuncCall: break; case OpCode.IgnorePropGet: break; case OpCode.IgnorePropSet: break; default: throw new ArgumentOutOfRangeException(); } } expList.RemoveAll(node => node is Expression exp && exp.Parent != null); //Save states ex[Const.FlagReg] = flag; context.BlockFinalStates[block] = ex; //Process next foreach (var succ in block.To) { BlockProcess(context, succ, ex); //TODO: deep copy flag? } }
private IExpression ParseUnaryExpression(ref IToken token) { IExpression unaryExpression = ParseLiteralExpression(ref token); if (unaryExpression != null) { token = tokenParser.GetNextToken(); } else if (token is MinusToken) { token = tokenParser.GetNextToken(); return(new UnaryMinusExpression(ParseUnaryExpression(ref token))); } else if (token is IdentifierToken) { IdentifierToken idToken = token as IdentifierToken; token = tokenParser.GetNextToken(); if (token is OpenParenthesisToken) { try { ParameterExpression[] args = ParseArgumentList(ref token); unaryExpression = new FunctionExpression(idToken, args); } catch (SyntaxErrorException e) { throw new SyntaxErrorException(e.Message, e, e.Expression, new FunctionExpression(idToken, e.Args)); } } else if (token is LambdaInvokeToken) { try { token = tokenParser.GetNextToken(); IExpression rightExpression = ParseExpression(ref token); unaryExpression = new LambdaExpression(idToken, rightExpression); } catch (SyntaxErrorException e) { throw new SyntaxErrorException(e.Message, e, e.Expression, new LambdaExpression(idToken, e.RootExpression)); } } else { unaryExpression = new IdentifierExpression(idToken); } } else if (token is OpenParenthesisToken) { token = tokenParser.GetNextToken(); IExpression complexExpression = ParseLogicalOrExpression(ref token); if (!(token is CloseParenthesisToken)) { throw new SyntaxErrorException("')' experado."); } token = tokenParser.GetNextToken(); unaryExpression = complexExpression; } else { throw new SyntaxErrorException("expressão esperada."); } //decide se é uma propery access expression while (token is DotToken) { token = tokenParser.GetNextToken(); if (!(token is IdentifierToken)) { token = tokenParser.GetNextToken(); throw new SyntaxErrorException("identificador esperado", unaryExpression, unaryExpression); } IdentifierToken id = token as IdentifierToken; unaryExpression = new PropertyAccessExpression(unaryExpression, id.IdentifierName); token = tokenParser.GetNextToken(); } return(unaryExpression); }