public IdentifierSetNode(IdentifierGetNode node) { Name = node.Name; TypePrefix = node.TypePrefix; ExpressionPrefix = node.ExpressionPrefix; AtmarkPrefix = node.AtmarkPrefix; }
public override void Compile(Emitter.Emitter emitter) { // check if there's an expression prefix and back it up if (Left.ExpressionPrefix != null) { // save to tmp variable var tmpVarName = emitter.CurrentMethod.Scope.CreateNewName(); var tmpVar = Expr.Var(tmpVarName, Left.ExpressionPrefix); tmpVar.Compile(emitter); Left.ExpressionPrefix = Expr.IdentifierGet(tmpVarName); } if (Right.ExpressionPrefix != null) { // save to tmp variable var tmpVarName = emitter.CurrentMethod.Scope.CreateNewName(); var tmpVar = Expr.Var(tmpVarName, Right.ExpressionPrefix); tmpVar.Compile(emitter); Right.ExpressionPrefix = Expr.IdentifierGet(tmpVarName); } // create temp variable var exchgVarName = emitter.CurrentMethod.Scope.CreateNewName(); var exchgNode = new IdentifierGetNode(exchgVarName); // create three assignable nodes var assignNodes = new SyntaxTreeNode[3]; assignNodes[0] = Expr.Var(exchgVarName, Left); assignNodes[1] = GetAssignableNode(Left, Right); assignNodes[2] = GetAssignableNode(Right, exchgNode); // affix them to the lexem and compile foreach(var curr in assignNodes) { curr.Lexem = Lexem; curr.Compile(emitter); } }
/// <summary> /// accessor = identifier, [ "(", { expr, "," }, ")" ] /// </summary> /// <returns></returns> public IdentifierNode ParseAccessor(bool allowInvoke = true) { // <name> IdentifierNode node; if (!PeekLexem(LexemType.Identifier)) Error(Resources.errIdentifierExpected); Lexem name = GetLexem(); SkipLexem(); // ? "(" // invoke a function with argument list in brackets if (allowInvoke && PeekLexem(LexemType.ParenOpen)) { SkipLexem(); node = new IdentifierInvokeNode(name.Data); bool first = true; while(!PeekLexem(LexemType.ParenClose, LexemType.EOF)) { // "," before each but the first argument if (!first) { if (!PeekLexem(LexemType.Comma)) Error(Resources.errCommaExpected); SkipLexem(); } (node as IdentifierInvokeNode).Parameters.Add(ParseExpr()); first = false; } // ")" if (!PeekLexem(LexemType.ParenClose)) Error(Resources.errParenExpected); SkipLexem(); } // bare invoke else if (allowInvoke && !PeekLexem(LexemType.NewLine) && PeekLexem(LexemTypeGroup.Parameter)) { node = new IdentifierInvokeNode(name.Data); (node as IdentifierInvokeNode).Parameters.Add(ParseExpr()); while(PeekLexem(LexemType.Comma)) { SkipLexem(); (node as IdentifierInvokeNode).Parameters.Add(ParseExpr()); } // check if a comma has been skipped? var nextLexem = GetLexem(0, true); if(LexemTypeGroup.Parameter.Contains(nextLexem.Type)) Error(Resources.errCommaExpected); } else node = new IdentifierGetNode(name.Data); node.Lexem = name; return node; }
/// <summary> /// array_expr = [ "-" ], ( literal | identifier | "(" expr ")" ) ; /// </summary> /// <returns></returns> public SyntaxTreeNode ParseArrayExpr() { SyntaxTreeNode node = null; // ? "-" var invert = false; if (PeekLexem(LexemType.Subtract)) { invert = true; SkipLexem(); } if (PeekLexem(LexemTypeGroup.Literal)) node = ParseLiteral(); else if (PeekLexem(LexemType.Identifier)) { var lexem = GetLexem(); var idNode = new IdentifierGetNode(lexem.Data); if (lexem.Data[0] == '@') { idNode.Name = idNode.Name.Substring(1, idNode.Name.Length - 1); idNode.AtmarkPrefix = true; } node = idNode; node.Lexem = lexem; SkipLexem(); } else if (PeekLexem(LexemType.ParenOpen)) { // "(" SkipLexem(); node = ParseExpr(); // ")" if (!PeekLexem(LexemType.ParenClose)) Error(Resources.errParenExpected); SkipLexem(true); } else Error(Resources.errArrayExpressionParensExpected); // invert if needed if (invert) node = new OperatorInvertNode(node); return node; }