public CodeBlock(CodeLine line, string method, CodeStatementCollection statements, BlockKind kind, CodeBlock parent, string endLabel, string exitLabel) { this.line = line; this.method = method; this.statements = statements; Type = BlockType.Expect; this.kind = kind; this.parent = parent; level = int.MaxValue; this.endLabel = endLabel; this.exitLabel = exitLabel; }
CodeMethodInvokeExpression ParseLabel(CodeLine line) { string code = line.Code; int z = code.Length - 1; string name = z > 0 ? code.Substring(0, z) : string.Empty; if (code.Length < 2 || code[z] != HotkeyBound) throw new ParseException("Invalid label name"); PushLabel(line, name, name, true); return LocalLabelInvoke(name); }
void PushLabel(CodeLine line, string name, string realname, bool fallthrough) { var last = CloseTopLabelBlock(); if (fallthrough && last != null) last.Statements.Add(LocalLabelInvoke(name)); var method = LocalMethod(name); var block = new CodeBlock(line, method.Name, method.Statements, CodeBlock.BlockKind.Label, blocks.Count == 0 ? null : blocks.Peek()) { Type = CodeBlock.BlockType.Within, Name = realname }; CloseTopSingleBlock(); blocks.Push(block); methods.Add(method.Name, method); }
public CodeBlock(CodeLine line, string method, CodeStatementCollection statements, BlockKind kind, CodeBlock parent) : this(line, method, statements, kind, parent, null, null) { }
public ParseException(string message, CodeLine line) : this(message, line.LineNumber, line.FileName) { }
public void ParseFunction(CodeLine line) { CloseTopLabelBlock(); string code = line.Code; int i; var buf = new StringBuilder(); #region Name string name; for (i = 0; i < code.Length; i++) { char sym = code[i]; if (IsIdentifier(sym)) buf.Append(sym); else if (sym == ParenOpen) { i++; break; } else throw new ParseException(ExUnexpected); } if (buf.Length == 0) throw new ParseException(ExUnexpected); name = buf.ToString(); buf.Length = 0; if (IsLocalMethodReference(name)) throw new ParseException("Duplicate function"); #endregion #region Parameters CodeBlock.BlockType blockType = CodeBlock.BlockType.Expect; bool str = false; bool stop = false; for (; i < code.Length; i++) { char sym = code[i]; switch (sym) { case StringBound: str = !str; goto default; case ParenClose: if (str) goto default; else stop = true; break; default: buf.Append(sym); break; } if (stop) break; } if (!stop) throw new ParseException("Expected closing parenthesis"); string param = buf.ToString(); buf.Length = 0; i++; #region Opening brace for (; i < code.Length; i++) { char sym = code[i]; if (sym == BlockOpen) { blockType = CodeBlock.BlockType.Within; break; } else if (IsCommentAt(code, i)) break; else if (!IsSpace(sym)) throw new ParseException(ExUnexpected); } #endregion #endregion #region Block var method = LocalMethod(name); method.Attributes = MemberAttributes.Static | MemberAttributes.AccessMask; var block = new CodeBlock(line, method.Name, method.Statements, CodeBlock.BlockKind.Function, blocks.Count == 0 ? null : blocks.Peek()); block.Type = blockType; CloseTopSingleBlock(); blocks.Push(block); var fix = ParseFunctionParameters(param); if (fix != null) method.Statements.Add(fix); #endregion methods.Add(method.Name, method); var type = typeof(Rusty.Core.GenericFunction); var typeref = new CodeTypeReference(); typeref.UserData.Add(RawData, type); var del = new CodeDelegateCreateExpression(typeref, new CodeTypeReferenceExpression(className), method.Name); var obj = VarAssign(VarRef(mainScope + ScopeVar + method.Name), del); prepend.Add(new CodeExpressionStatement(obj)); }