/// <summary> /// Matches a <c>Primary</c> non-terminal. /// </summary> /// <returns><c>true</c> if the <c>Primary</c> was matched successfully; otherwise, <c>false</c>.</returns> /// <remarks> /// The non-terminal can start with: <c>Nil</c>, <c>False</c>, <c>True</c>, <c>Number</c>, <c>String</c>. /// </remarks> protected virtual bool MatchPrimary(out Expression expression) { expression = null; if (this.TokenIs(this.LookAheadToken, LuatTokenId.Nil)) { if (!this.Match(LuatTokenId.Nil)) return false; expression = new NilExpression( this.Token.TextRange ); } else if (this.TokenIs(this.LookAheadToken, LuatTokenId.False)) { if (!this.Match(LuatTokenId.False)) return false; expression = new BooleanExpression( false, this.Token.TextRange); } else if (this.TokenIs(this.LookAheadToken, LuatTokenId.True)) { if (!this.Match(LuatTokenId.True)) return false; expression = new BooleanExpression( true, this.Token.TextRange); } else if (this.TokenIs(this.LookAheadToken, LuatTokenId.Number)) { if (!this.Match(LuatTokenId.Number)) return false; expression = new NumberExpression( Convert.ToDouble(this.TokenText), this.Token.TextRange ); } else if (this.TokenIs(this.LookAheadToken, LuatTokenId.String)) { if (!this.MatchStringExpression(out expression)) return false; } else return false; return true; }
public override bool Install(LuatScript script) { if (false == base.Install(script)) { return(false); } if (false == IsLocal && Values.Count == 0) { // Illegal assignment statement, assumes parser has already emitted error. return(false); } int variableCount = Variables.Count; for (int variableIndex = 0; variableIndex < variableCount; ++variableIndex) { Expression lhs = Variables[variableIndex] as Expression; Expression rhs; if (variableIndex < Values.Count) { rhs = Values[variableIndex] as Expression; } else { rhs = new NilExpression(lhs.TextRange); rhs.Resolve(script); this.ChildNodes.Add(rhs); } LuatVariable variable = lhs.Resolve(script) as LuatVariable; bool bValid = false; do { if (null == variable) { break; } if (variable.IsReadOnly) { this.AddError(string.Format("{0} is read-only", lhs.DisplayText)); break; } bValid = true; }while (false); if (false == bValid) { // Failed to resolve or create the name. // Undo all the assignments we've done and return incomplete. Uninstall(script); return(false); } string displayText = string.Format("{0} = {1}", lhs.DisplayText, rhs.DisplayText); LuatValue.IReference reference = new Parser.AST.Expression.Reference(script, rhs, displayText); variable.AddAssignment(reference); AddUninstallAction(script, delegate() { variable.RemoveAssignment(reference); }); } return(true); }
/// <summary> /// Matches a <c>ExpressionNoFunctionInner</c> non-terminal. /// </summary> /// <returns><c>true</c> if the <c>ExpressionNoFunctionInner</c> was matched successfully; otherwise, <c>false</c>.</returns> /// <remarks> /// The non-terminal can start with: <c>OpenParenthesis</c>, <c>OpenCurlyBrace</c>, <c>Identifier</c>, <c>TripleDot</c>, <c>Nil</c>, <c>False</c>, <c>True</c>, <c>Number</c>, <c>Subtraction</c>, <c>Not</c>, <c>Hash</c>, <c>String</c>. /// </remarks> protected virtual bool MatchExpressionNoFunctionInner(out Expression expression) { expression = null; if (this.IsInMultiMatchSet(6, this.LookAheadToken)) { if (!this.MatchPrimary(out expression)) return false; } else if (this.TokenIs(this.LookAheadToken, LuatTokenId.TripleDot)) { if (!this.Match(LuatTokenId.TripleDot)) return false; expression = new NilExpression( this.Token.TextRange ); } else if (((this.TokenIs(this.LookAheadToken, LuatTokenId.OpenParenthesis)) || (this.TokenIs(this.LookAheadToken, LuatTokenId.OpenCurlyBrace)) || (this.TokenIs(this.LookAheadToken, LuatTokenId.Identifier)))) { if (this.TokenIs(this.LookAheadToken, LuatTokenId.Identifier)) { if (!this.MatchVariable(out expression)) return false; } else if (this.TokenIs(this.LookAheadToken, LuatTokenId.OpenCurlyBrace)) { if (!this.MatchTableConstructor(out expression)) return false; } else if (this.TokenIs(this.LookAheadToken, LuatTokenId.OpenParenthesis)) { if (!this.MatchParenthesis(out expression)) return false; } else return false; while (this.IsInMultiMatchSet(7, this.LookAheadToken)) { if (((this.TokenIs(this.LookAheadToken, LuatTokenId.Dot)) || (this.TokenIs(this.LookAheadToken, LuatTokenId.OpenSquareBracket)))) { if (!this.MatchIndex(ref expression)) return false; } else if (this.IsInMultiMatchSet(8, this.LookAheadToken)) { if (!this.MatchCallSuffix(ref expression)) return false; } else return false; } } else if (((this.TokenIs(this.LookAheadToken, LuatTokenId.Subtraction)) || (this.TokenIs(this.LookAheadToken, LuatTokenId.Not)) || (this.TokenIs(this.LookAheadToken, LuatTokenId.Hash)))) { int start = this.LookAheadToken.StartOffset; OperatorType operatorType; if (!this.MatchUnaryOp(out operatorType)) return false; Expression rhs = null; if (!this.MatchExpression(out rhs)) return false; expression = new UnaryExpression( operatorType, rhs, new TextRange( start, this.Token.EndOffset) ); } else return false; while (this.IsInMultiMatchSet(9, this.LookAheadToken)) { OperatorType operatorType; if (!this.MatchBinaryOp(out operatorType)) return false; Expression rhs = null; if (!this.MatchExpression(out rhs)) return false; expression = new BinaryExpression( operatorType, expression, rhs ); } return true; }