AsmStatement ParseAsmStatement(IBlockNode Scope, IStatement Parent) { Step(); var s = new AsmStatement() { Location = t.Location, Parent = Parent }; Expect(OpenCurlyBrace); var l = new List<AbstractStatement>(); while (!IsEOF && laKind != (CloseCurlyBrace)) { bool retrying = false; Retry: bool noStatement = false; if (laKind == Align) { var als = new AsmStatement.AlignStatement() { Location = la.Location, Parent = s }; Step(); als.ValueExpression = Expression(Scope); l.Add(als); Step(); } else if (laKind == Identifier) { var opCode = AsmStatement.InstructionStatement.OpCode.__UNKNOWN__; var dataType = AsmStatement.RawDataStatement.DataType.__UNKNOWN__; if (Peek(1).Kind == Colon) { l.Add(new LabeledStatement() { Location = la.Location, Parent = s, Identifier = la.Value, EndLocation = Peek(1).EndLocation }); Step(); Step(); if (laKind == Semicolon) Step(); continue; } if (AsmStatement.RawDataStatement.TryParseDataType(la.Value, out dataType)) l.Add(new AsmStatement.RawDataStatement() { Location = la.Location, Parent = s, TypeOfData = dataType }); else if (AsmStatement.InstructionStatement.TryParseOpCode(la.Value, out opCode)) l.Add(new AsmStatement.InstructionStatement() { Location = la.Location, Parent = s, Operation = opCode }); else switch (la.Value.ToLower()) { case "pause": SynErr(Identifier, "Pause is not supported by dmd's assembler. Use `rep; nop;` instead to achieve the same effect."); break; case "even": var als = new AsmStatement.AlignStatement() { Location = la.Location, Parent = s }; als.ValueExpression = new IdentifierExpression(2) { Location = la.Location, EndLocation = la.EndLocation }; l.Add(als); break; case "naked": noStatement = true; break; default: SynErr(Identifier, "Unknown op-code!"); l.Add(new AsmStatement.InstructionStatement() { Location = la.Location, Parent = s, Operation = AsmStatement.InstructionStatement.OpCode.__UNKNOWN__ }); break; } Step(); if (noStatement && laKind != Semicolon) SynErr(Semicolon); var parentStatement = noStatement ? s : l[l.Count - 1]; var args = new List<IExpression>(); if (IsEOF) args.Add(new TokenExpression(Incomplete)); else if (laKind != Semicolon) { while (true) { if (laKind == CloseCurlyBrace) { // This is required as a custom error message because // it would complain about finding an identifier instead. SynErr(Semicolon, "; expected, } found"); break; } var e = ParseAsmExpression(Scope, parentStatement); if (e != null) args.Add(e); if (laKind == Comma) { Step(); continue; } if (IsEOF) args.Add(new TokenExpression(Incomplete)); if (!Expect(Semicolon)) { while (laKind != Semicolon && laKind != CloseCurlyBrace && !IsEOF) Step(); if (laKind == Semicolon) Step(); } break; } } else Step(); if (parentStatement is AsmStatement.InstructionStatement) ((AsmStatement.InstructionStatement)parentStatement).Arguments = args.ToArray(); else if (parentStatement is AsmStatement.RawDataStatement) ((AsmStatement.RawDataStatement)parentStatement).Data = args.ToArray(); } else if (laKind != Semicolon) { string val; if (!retrying && Keywords.TryGetValue(laKind, out val)) { la.LiteralValue = val; la.Kind = Identifier; Lexer.laKind = Identifier; retrying = true; goto Retry; } else { noStatement = true; SynErr(Identifier); Step(); } } else Step(); if (!noStatement) l[l.Count - 1].EndLocation = t.Location; } if (!Expect(CloseCurlyBrace) && (t.Kind == OpenCurlyBrace || t.Kind == Semicolon) && IsEOF) l.Add(new AsmStatement.InstructionStatement() { Operation = AsmStatement.InstructionStatement.OpCode.__UNKNOWN__ }); s.EndLocation = t.EndLocation; s.Instructions = l.ToArray(); return s; }
public override void Visit(AsmStatement s) { scopedStatement = s; base.Visit(s); scopedStatement = null; }
AsmStatement AsmStatement(IStatement Parent) { Step(); var s = new AsmStatement() { Location = t.Location, Parent = Parent }; LastParsedObject = s; Expect(OpenCurlyBrace); var l = new List<string>(); var curInstr = ""; while (!IsEOF && laKind != (CloseCurlyBrace)) { if (laKind == Semicolon) { l.Add(curInstr.Trim()); curInstr = ""; } else curInstr += laKind == Identifier ? la.Value : DTokens.GetTokenString(laKind); Step(); } Expect(CloseCurlyBrace); s.EndLocation = t.EndLocation; return s; }
public override DefiniteAssignmentStatus VisitAsmStatement(AsmStatement unsafeStatement, DefiniteAssignmentStatus data) { return(data); }
public void Visit(AsmStatement asmStatement) { }
public override void Visit(AsmStatement.InstructionStatement s) { if (s.Operation == AsmStatement.InstructionStatement.OpCode.__UNKNOWN__) { prv = new InlineAsmCompletionProvider(s, cdgen); scopedStatement = s; halt = true; } else base.Visit(s); }
public override ControlFlowNode VisitAsmStatement(AsmStatement safeStatement, ControlFlowNode data) { ControlFlowNode bodyEnd = HandleEmbeddedStatement(safeStatement.Body, data); return(CreateConnectedEndNode(safeStatement, bodyEnd)); }
IStatement Statement(bool BlocksAllowed = true, bool EmptyAllowed = true, IBlockNode Scope = null, IStatement Parent=null) { IStatement ret = null; if (EmptyAllowed && laKind == Semicolon) { Step(); return null; } if (BlocksAllowed && laKind == OpenCurlyBrace) return BlockStatement(Scope,Parent); #region LabeledStatement (loc:... goto loc;) if (laKind == Identifier && Lexer.CurrentPeekToken.Kind == Colon) { Step(); ret = (new LabeledStatement() { StartLocation = t.Location, Identifier = t.Value, Parent = Parent }); LastParsedObject = ret; Step(); ret.EndLocation = t.EndLocation; return ret; } #endregion #region IfStatement else if (laKind == (If) || (laKind == Static && Lexer.CurrentPeekToken.Kind == If)) { bool isStatic = laKind==Static; if (isStatic) Step(); Step(); var dbs = new IfStatement() { StartLocation = t.Location, IsStatic = isStatic, Parent = Parent }; LastParsedObject = dbs; Expect(OpenParenthesis); // IfCondition IfCondition(dbs); Expect(CloseParenthesis); // ThenStatement dbs.ThenStatement = Statement(Scope:Scope,Parent:dbs); // ElseStatement if (laKind == (Else)) { Step(); dbs.ElseStatement = Statement(Scope: Scope, Parent: dbs); } dbs.EndLocation = t.EndLocation; return dbs; } #endregion #region WhileStatement else if (laKind == While) { Step(); var dbs = new WhileStatement() { StartLocation = t.Location, Parent = Parent }; LastParsedObject = dbs; Expect(OpenParenthesis); dbs.Condition = Expression(Scope); Expect(CloseParenthesis); dbs.ScopedStatement = Statement(Scope: Scope, Parent: dbs); dbs.EndLocation = t.EndLocation; return dbs; } #endregion #region DoStatement else if (laKind == (Do)) { Step(); var dbs = new WhileStatement() { StartLocation = t.Location, Parent = Parent }; LastParsedObject = dbs; dbs.ScopedStatement = Statement(Scope: Scope, Parent: dbs); Expect(While); Expect(OpenParenthesis); dbs.Condition = Expression(Scope); Expect(CloseParenthesis); dbs.EndLocation = t.EndLocation; return dbs; } #endregion #region ForStatement else if (laKind == (For)) { Step(); var dbs = new ForStatement { StartLocation = t.Location, Parent = Parent }; LastParsedObject = dbs; Expect(OpenParenthesis); // Initialize if (laKind != Semicolon) dbs.Initialize = Statement(false, Scope: Scope, Parent: dbs); // Against the D language theory, blocks aren't allowed here! else Step(); // Enforce a trailing semi-colon only if there hasn't been an expression (the ; gets already skipped in there) // Expect(Semicolon); // Test if (laKind != (Semicolon)) dbs.Test = Expression(Scope); Expect(Semicolon); // Increment if (laKind != (CloseParenthesis)) dbs.Increment= Expression(Scope); Expect(CloseParenthesis); dbs.ScopedStatement = Statement(Scope: Scope, Parent: dbs); dbs.EndLocation = t.EndLocation; return dbs; } #endregion #region ForeachStatement else if (laKind == (Foreach) || laKind == (Foreach_Reverse)) { Step(); var dbs = new ForeachStatement() { StartLocation = t.Location, IsReverse = t.Kind == Foreach_Reverse, Parent=Parent }; LastParsedObject = dbs; Expect(OpenParenthesis); var tl = new List<DVariable>(); bool init = true; while (init || laKind == (Comma)) { if (!init) Step(); init = false; var forEachVar = new DVariable(); LastParsedObject = forEachVar; forEachVar.StartLocation = la.Location; if (laKind == (Ref)) { Step(); forEachVar.Attributes.Add(new DAttribute(Ref)); } if (laKind == (Identifier) && (Lexer.CurrentPeekToken.Kind == (Semicolon) || Lexer.CurrentPeekToken.Kind == Comma)) { Step(); forEachVar.Name = t.Value; } else { forEachVar.Type = Type(); if (laKind == Identifier) { Expect(Identifier); forEachVar.Name = t.Value; } } forEachVar.EndLocation = t.EndLocation; tl.Add(forEachVar); } dbs.ForeachTypeList = tl.ToArray(); Expect(Semicolon); dbs.Aggregate = Expression(Scope); // ForeachRangeStatement if (laKind == DoubleDot) { Step(); //TODO: Put this in the expression variable Expression(); } Expect(CloseParenthesis); dbs.ScopedStatement = Statement(Scope: Scope, Parent: dbs); dbs.EndLocation = t.EndLocation; return dbs; } #endregion #region [Final] SwitchStatement else if ((laKind == (Final) && Lexer.CurrentPeekToken.Kind == (Switch)) || laKind == (Switch)) { var dbs = new SwitchStatement { StartLocation = la.Location, Parent = Parent }; LastParsedObject = dbs; if (laKind == (Final)) { dbs.IsFinal = true; Step(); } Step(); Expect(OpenParenthesis); dbs.SwitchExpression = Expression(Scope); Expect(CloseParenthesis); dbs.ScopedStatement = Statement(Scope: Scope, Parent: dbs); dbs.EndLocation = t.EndLocation; return dbs; } #endregion #region CaseStatement else if (laKind == (Case)) { Step(); var dbs = new SwitchStatement.CaseStatement() { StartLocation = la.Location, Parent = Parent }; LastParsedObject = dbs; dbs.ArgumentList = Expression(Scope); Expect(Colon); // CaseRangeStatement if (laKind == DoubleDot) { Step(); Expect(Case); dbs.LastExpression = AssignExpression(); Expect(Colon); } var sl = new List<IStatement>(); while (laKind != Case && laKind != Default && laKind != CloseCurlyBrace && !IsEOF) { var stmt = Statement(Scope: Scope, Parent: dbs); if (stmt != null) { stmt.Parent = dbs; sl.Add(stmt); } } dbs.ScopeStatementList = sl.ToArray(); dbs.EndLocation = t.EndLocation; return dbs; } #endregion #region Default else if (laKind == (Default)) { Step(); var dbs = new SwitchStatement.DefaultStatement() { StartLocation = la.Location, Parent = Parent }; LastParsedObject = dbs; Expect(Colon); var sl = new List<IStatement>(); while (laKind != Case && laKind != Default && laKind != CloseCurlyBrace && !IsEOF) { var stmt = Statement(Scope: Scope, Parent: dbs); if (stmt != null) { stmt.Parent = dbs; sl.Add(stmt); } } dbs.ScopeStatementList = sl.ToArray(); dbs.EndLocation = t.EndLocation; return dbs; } #endregion #region Continue | Break else if (laKind == (Continue)) { Step(); var s = new ContinueStatement() { StartLocation = t.Location, Parent = Parent }; LastParsedObject = s; if (laKind == (Identifier)) { Step(); s.Identifier = t.Value; } Expect(Semicolon); s.EndLocation = t.EndLocation; return s; } else if (laKind == (Break)) { Step(); var s = new BreakStatement() { StartLocation = t.Location, Parent = Parent }; LastParsedObject = s; if (laKind == (Identifier)) { Step(); s.Identifier = t.Value; } Expect(Semicolon); s.EndLocation = t.EndLocation; return s; } #endregion #region Return else if (laKind == (Return)) { Step(); var s = new ReturnStatement() { StartLocation = t.Location, Parent = Parent }; LastParsedObject = s; if (laKind != (Semicolon)) s.ReturnExpression = Expression(Scope); Expect(Semicolon); s.EndLocation = t.EndLocation; return s; } #endregion #region Goto else if (laKind == (Goto)) { Step(); var s = new GotoStatement() { StartLocation = t.Location, Parent = Parent }; LastParsedObject = s; if (laKind == (Identifier)) { Step(); s.StmtType = GotoStatement.GotoStmtType.Identifier; s.LabelIdentifier = t.Value; } else if (laKind == Default) { Step(); s.StmtType = GotoStatement.GotoStmtType.Default; } else if (laKind == (Case)) { Step(); s.StmtType = GotoStatement.GotoStmtType.Case; if (laKind != (Semicolon)) s.CaseExpression = Expression(Scope); } Expect(Semicolon); s.EndLocation = t.EndLocation; return s; } #endregion #region WithStatement else if (laKind == (With)) { Step(); var dbs = new WithStatement() { StartLocation = t.Location, Parent = Parent }; LastParsedObject = dbs; Expect(OpenParenthesis); // Symbol dbs.WithExpression = Expression(Scope); Expect(CloseParenthesis); dbs.ScopedStatement = Statement(Scope: Scope, Parent: dbs); dbs.EndLocation = t.EndLocation; return dbs; } #endregion #region SynchronizedStatement else if (laKind == (Synchronized)) { Step(); var dbs = new SynchronizedStatement() { StartLocation = t.Location, Parent = Parent }; LastParsedObject = dbs; if (laKind == (OpenParenthesis)) { Step(); dbs.SyncExpression = Expression(Scope); Expect(CloseParenthesis); } dbs.ScopedStatement = Statement(Scope: Scope, Parent: dbs); dbs.EndLocation = t.EndLocation; return dbs; } #endregion #region TryStatement else if (laKind == (Try)) { Step(); var s = new TryStatement() { StartLocation = t.Location, Parent = Parent }; LastParsedObject = s; s.ScopedStatement = Statement(Scope: Scope, Parent: s); if (!(laKind == (Catch) || laKind == (Finally))) SemErr(Catch, "At least one catch or a finally block expected!"); var catches = new List<TryStatement.CatchStatement>(); // Catches while (laKind == (Catch)) { Step(); var c = new TryStatement.CatchStatement() { StartLocation = t.Location, Parent = s }; LastParsedObject = c; // CatchParameter if (laKind == (OpenParenthesis)) { Step(); if (laKind == CloseParenthesis) { SemErr(CloseParenthesis, "Catch parameter expected, not ')'"); Step(); } else { var catchVar = new DVariable(); LastParsedObject = catchVar; var tt = la; //TODO? catchVar.Type = BasicType(); if (laKind != Identifier) { la = tt; catchVar.Type = new IdentifierDeclaration("Exception"); } Expect(Identifier); catchVar.Name = t.Value; Expect(CloseParenthesis); c.CatchParameter = catchVar; } } c.ScopedStatement = Statement(Scope: Scope, Parent: c); c.EndLocation = t.EndLocation; catches.Add(c); } if(catches.Count>0) s.Catches = catches.ToArray(); if (laKind == (Finally)) { Step(); var f = new TryStatement.FinallyStatement() { StartLocation = t.Location, Parent = Parent }; LastParsedObject = f; f.ScopedStatement = Statement(); f.EndLocation = t.EndLocation; s.FinallyStmt = f; } s.EndLocation = t.EndLocation; return s; } #endregion #region ThrowStatement else if (laKind == (Throw)) { Step(); var s = new ThrowStatement() { StartLocation = t.Location, Parent = Parent }; LastParsedObject = s; s.ThrowExpression = Expression(Scope); Expect(Semicolon); s.EndLocation = t.EndLocation; return s; } #endregion #region ScopeGuardStatement else if (laKind == (DTokens.Scope) && Lexer.CurrentPeekToken.Kind==OpenParenthesis) { Step(); var s = new ScopeGuardStatement() { StartLocation = t.Location, Parent = Parent }; LastParsedObject = s; if (laKind == OpenParenthesis) { Expect(OpenParenthesis); if(Expect(Identifier) && t.Value!=null) // exit, failure, success { s.GuardedScope = t.Value.ToLower(); } Expect(CloseParenthesis); } s.ScopedStatement = Statement(Scope: Scope, Parent: s); s.EndLocation = t.EndLocation; return s; } #endregion #region AsmStmt else if (laKind == (Asm)) { Step(); var s = new AsmStatement() { StartLocation = t.Location, Parent = Parent }; LastParsedObject = s; Expect(OpenCurlyBrace); var l=new List<string>(); var curInstr = ""; while (!IsEOF && laKind != (CloseCurlyBrace)) { if (laKind == Semicolon) { l.Add(curInstr.Trim()); curInstr = ""; } else curInstr += laKind==Identifier? la.Value: DTokens.GetTokenString(laKind); Step(); } Expect(CloseCurlyBrace); s.EndLocation = t.EndLocation; return s; } #endregion #region PragmaStatement else if (laKind == (Pragma)) { var s=_Pragma(); s.Parent = Parent; s.ScopedStatement = Statement(Scope: Scope, Parent: s); s.EndLocation = t.EndLocation; return s; } #endregion #region MixinStatement //TODO: Handle this one in terms of adding it to the node structure else if (laKind == (Mixin)) { // TemplateMixin if (Peek(1).Kind != OpenParenthesis) return TemplateMixin(); else { Step(); var s = new MixinStatement() { StartLocation = t.Location, Parent = Parent }; LastParsedObject = s; Expect(OpenParenthesis); s.MixinExpression = AssignExpression(Scope); Expect(CloseParenthesis); Expect(Semicolon); s.EndLocation = t.EndLocation; return s; } } #endregion #region Conditions if (laKind == Debug) { Step(); var s = new ConditionStatement.DebugStatement() { StartLocation = t.Location, Parent = Parent }; LastParsedObject = s; if (laKind == OpenParenthesis) { Step(); if (laKind == Identifier || laKind == Literal) { Step(); if (laKind == Literal) s.DebugIdentifierOrLiteral = t.LiteralValue; else s.DebugIdentifierOrLiteral = t.Value; } else SynErr(t.Kind, "Identifier or Literal expected, "+DTokens.GetTokenString(t.Kind)+" found"); Expect(CloseParenthesis); } s.ScopedStatement = Statement(Scope: Scope, Parent: s); if (laKind == Else) { Step(); s.ElseStatement = Statement(Scope: Scope,Parent:s); } s.EndLocation = t.EndLocation; return s; } if (laKind == Version) { Step(); var s = new ConditionStatement.VersionStatement() { StartLocation = t.Location, Parent = Parent }; if (laKind == OpenParenthesis) { Step(); if (laKind == Identifier || laKind == Literal || laKind==Unittest) { Step(); if(laKind==Unittest) s.VersionIdentifierOrLiteral = "unittest"; else if(laKind==Literal) s.VersionIdentifierOrLiteral=t.LiteralValue; else s.VersionIdentifierOrLiteral=t.Value; } else SynErr(t.Kind, "Identifier or Literal expected, " + DTokens.GetTokenString(t.Kind) + " found"); Expect(CloseParenthesis); } s.ScopedStatement = Statement(Parent:s); if (laKind == Else) { Step(); s.ElseStatement = Statement(Parent:s); } s.EndLocation = t.EndLocation; return s; } #endregion #region (Static) AssertExpression else if (laKind == Assert || (laKind == Static && PK(Assert))) { var s = new AssertStatement() { StartLocation = la.Location, IsStatic = laKind == Static, Parent = Parent }; LastParsedObject = s; if (s.IsStatic) Step(); s.AssertExpression = AssignExpression(Scope); Expect(Semicolon); s.EndLocation = t.EndLocation; return s; } #endregion #region D1: VolatileStatement else if (laKind == Volatile) { Step(); var s = new VolatileStatement() { StartLocation = t.Location, Parent = Parent }; LastParsedObject = s; s.ScopedStatement = Statement(Scope: Scope,Parent:s); s.EndLocation = t.EndLocation; return s; } #endregion // ImportDeclaration else if (laKind == Import) ImportDeclaration(); else if (!(ClassLike[laKind] || BasicTypes[laKind] || laKind == Enum || Modifiers[laKind] || laKind==PropertyAttribute || laKind == Alias || laKind == Typedef) && IsAssignExpression()) { var s = new ExpressionStatement() { StartLocation = la.Location, Parent = Parent }; LastParsedObject = s; // a==b, a=9; is possible -> Expressions can be there, not only single AssignExpressions! s.Expression = Expression(Scope); if (Expect(Semicolon)) LastParsedObject = null; s.EndLocation = t.EndLocation; return s; } else { var s = new DeclarationStatement() { StartLocation = la.Location, Parent = Parent }; LastParsedObject = s; s.Declarations = Declaration(Scope); if (Scope != null && s.Declarations != null && s.Declarations.Length > 0) foreach (var decl in s.Declarations) decl.Parent = Scope; s.EndLocation = t.EndLocation; return s; } return null; }
public override void Visit(AsmStatement s) { scopedStatement = s; base.Visit(s); }
public void Visit(AsmStatement.RawDataStatement dataStatement) { }
public void Visit(AsmStatement.AlignStatement alignStatement) { }
public void Visit(AsmStatement.InstructionStatement instrStatement) { }
public override void Visit(AsmStatement.RawDataStatement s) { scopedStatement = s; base.Visit(s); scopedStatement = null; }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) { AsmStatement o = other as AsmStatement; return(o != null && this.Body.DoMatch(o.Body, match)); }
public override void Visit(AsmStatement s) { base.Visit(s); }