internal static ArgumentToken ReadArgument(TokenCollection stream) { if (stream.NextIsEndOfLine) { throw new HspLogicalLineException("引数:読み込み中にスタックが空になった"); } bool hasBracket = stream.NextIsBracketStart; //括弧読み捨て。 if (hasBracket) { stream.GetNextToken(); } List <ExpressionToken> exps = new List <ExpressionToken>(); bool firstArgIsNull = stream.NextIsEndOfParam; //一度引数を読み始めたら行末か')'まで読みきる while (!stream.NextIsEndOfLine) { if (hasBracket & stream.NextIsBracketEnd) { //括弧読み捨て & 引数終了 stream.GetNextToken(); break; } exps.Add(ReadExpression(stream)); } return(new ArgumentToken(exps, hasBracket, firstArgIsNull)); }
private static LogicalLine readMcall(TokenCollection stream) { int start = stream.Position; McallFunctionPrimitive mcall = stream.GetNextToken() as McallFunctionPrimitive; if (mcall == null) { throw new HspLogicalLineException("mcall:mcallプリミティブ以外からスタート"); } if (stream.NextIsEndOfLine) { stream.Position = start; return((LogicalLine)readCommand(stream)); } ExpressionToken exp = CodeTokenFactory.ReadExpression(stream); if (exp.CanRpnConvert) //RPN変換ができるなら普通の関数として扱う。 { stream.Position = start; return((LogicalLine)readCommand(stream)); } stream.Position = start; stream.GetNextToken(); VariablePrimitive var = stream.GetNextToken() as VariablePrimitive; if (var == null) { throw new HspLogicalLineException("mcall行:変換不能な形式"); } if (stream.NextIsBracketStart) //mcall の記法は配列変数を認めない { throw new HspLogicalLineException("mcall行:変換不能な形式"); } if (stream.NextIsEndOfLine) { throw new HspLogicalLineException("mcall行:変換不能な形式"); } exp = CodeTokenFactory.ReadExpression(stream); if (stream.NextIsEndOfLine) { return(new McallStatement(mcall, var, exp, null)); } ArgumentToken arg = CodeTokenFactory.ReadArgument(stream); if (stream.NextIsEndOfLine) { return(new McallStatement(mcall, var, exp, arg)); } throw new HspLogicalLineException("mcall行:余分なトークンがある"); }
/// <summary> /// If,elseステートメントの開始 /// </summary> /// <param defaultName="primitives"></param> /// <returns></returns> private static IfStatement readIf(TokenCollection stream) { IfStatementPrimitive token = stream.GetNextToken() as IfStatementPrimitive; if (token == null) { throw new HspLogicalLineException("条件分岐行:条件分岐プリミティブ以外からスタート"); } //elseには式がない。 if (stream.NextIsEndOfLine) { return(new IfStatement(token)); } else { //式を読む。あまりが出なければOK ArgumentToken arg = CodeTokenFactory.ReadArgument(stream); if (stream.NextIsEndOfLine) { return(new IfStatement(token, arg)); } } throw new HspLogicalLineException("条件分岐行:余分なトークンがある"); }
private static OnStatement readOn(TokenCollection stream) { OnFunctionPrimitive token = stream.GetNextToken() as OnFunctionPrimitive; if (token == null) { throw new HspLogicalLineException("on条件分岐行:条件分岐プリミティブ以外からスタート"); } //式がないこともあるかもしれない(実行時エラー) if (stream.NextIsEndOfLine) { return(new OnStatement(token, null, null)); } //式を読む。goto/gosubがないこともあるかもしれない(実行時エラー) ExpressionToken exp = CodeTokenFactory.ReadExpression(stream); if (stream.NextIsEndOfLine) { return(new OnStatement(token, exp, null)); } //goto/gosub関数を読む。goto/gosub以外でもコンパイルは通る(実行時エラー) //この関数には()がつかない。 FunctionToken func = CodeTokenFactory.ReadFunction(stream, false); if (stream.NextIsEndOfLine) { return(new OnStatement(token, exp, func)); } //まだあまってたらエラーね。 throw new HspLogicalLineException("on条件分岐行:余分なトークンがある"); }
internal static FunctionToken ReadFunction(TokenCollection stream, bool hasBracket) { if (stream.NextIsEndOfStream) { throw new HspLogicalLineException("関数:読み込み中にスタックが空になった"); } FunctionPrimitive token = stream.GetNextToken() as FunctionPrimitive; if (token == null) { throw new HspLogicalLineException("関数:関数プリミティブ以外からスタート"); } //行末なら強制的に終了 if (stream.NextIsEndOfLine) { return(new FunctionToken(token)); } //ゴーストラベル処理 if (token.HasGhostLabel && (stream.NextToken.CodeType == HspCodeType.Label)) { stream.GetNextToken(); if (stream.NextIsEndOfLine) { return(new FunctionToken(token)); } } //次が'('なら引数読み込み if (stream.NextIsBracketStart) { return(new FunctionToken(token, ReadArgument(stream))); } //どちらでもないなら、hasBracketで分岐 //hasBracket =falseなら強制的に引数ありに。 if (hasBracket) { return(new FunctionToken(token)); } else { return(new FunctionToken(token, ReadArgument(stream))); } }
private static object ReadLiteral(TokenCollection stream) { if (stream.NextIsEndOfLine) { throw new HspLogicalLineException("リテラル:読み込み中にスタックが空になった"); } //リテラルプリティブ読み込み LiteralPrimitive token = stream.GetNextToken() as LiteralPrimitive; if (token == null) { throw new HspLogicalLineException("リテラル:不適切な要素を検出"); } return(new LiteralToken(token)); }
internal static OperatorToken ReadOperator(TokenCollection stream) { if (stream.NextIsEndOfLine) { throw new HspLogicalLineException("演算子:読み込み中にスタックが空になった"); } //変数プリティブ読み込み OperatorPrimitive token = stream.GetNextToken() as OperatorPrimitive; if (token == null) { throw new HspLogicalLineException("演算子:不適切な要素を検出"); } return(new OperatorToken(token)); }
internal static VariableToken ReadVariable(TokenCollection stream) { if (stream.NextIsEndOfStream) { throw new HspLogicalLineException("変数:読み込み中にスタックが空になった"); } //変数プリティブ読み込み VariablePrimitive token = stream.GetNextToken() as VariablePrimitive; if (token == null) { throw new HspLogicalLineException("変数:変数プリミティブ以外からスタート"); } //次が括弧ならば配列変数 if (stream.NextIsBracketStart) { return(new VariableToken(token, ReadArgument(stream))); } //そうでなければ普通の変数 return(new VariableToken(token)); //if (parser.NextIsEndOfLine) // return VariableToken(token); }