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))); } }
internal static ExpressionToken ReadExpression(TokenCollection stream) { if (stream.NextIsEndOfLine) { throw new HspLogicalLineException("式:読み込み中にスタックが空になった"); } ExpressionTermToken elem = null; List <ExpressionTermToken> elements = new List <ExpressionTermToken>(); do //最低一つはパラメータがあるはず。 { if (stream.NextIsBracketEnd) { break; } if (stream.NextToken is OperatorPrimitive) { elem = (ExpressionTermToken)(ReadOperator(stream)); } else if (stream.NextToken is LiteralPrimitive) { elem = (ExpressionTermToken)(ReadLiteral(stream)); } else if (stream.NextToken is FunctionPrimitive) { elem = (ExpressionTermToken)(ReadFunction(stream, true)); } else if (stream.NextToken is VariablePrimitive) { elem = (ExpressionTermToken)(ReadVariable(stream)); } else { throw new HspLogicalLineException("式:不適切な要素を検出"); } elements.Add(elem); } while (!stream.NextIsEndOfParam); ExpressionToken ret = new ExpressionToken(elements); ret.RpnConvert(); return(ret); }
internal TokenCollection GetLine() { if (NextIsEndOfStream) { return(null); } List <PrimitiveToken> list = new List <PrimitiveToken>(); list.Add(primitives[position]); position++; while (position < primitives.Count) { if (primitives[position].IsLineHead) { break; } list.Add(primitives[position]); position++; } TokenCollection ret = new TokenCollection(); ret.primitives = list; return(ret); }
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); }
private static OnEventStatement readOnEvent(TokenCollection stream) { OnEventFunctionPrimitive token = stream.GetNextToken() as OnEventFunctionPrimitive; if (token == null) { throw new HspLogicalLineException("on条件分岐行:条件分岐プリミティブ以外からスタート"); } //goto/gosubがないこともあるかもしれない(実行時エラー) if (stream.NextIsEndOfLine) { return(new OnEventStatement(token, null)); } //goto/gosub関数を読む。goto/gosub以外でもコンパイルは通る(実行時エラー) //この関数には()がつかない。 FunctionToken func = CodeTokenFactory.ReadFunction(stream, false); if (stream.NextIsEndOfLine) { return(new OnEventStatement(token, func)); } //まだあまってたらエラーね。 throw new HspLogicalLineException("on条件分岐行:余分なトークンがある"); }
//外から見えるのはここだけ /// <summary> /// 一行分のTokenCollectionからLogicalLineを作成する /// </summary> /// <param defaultName="parser"></param> /// <returns></returns> internal static LogicalLine GetCodeToken(TokenCollection stream) { if (stream == null) { return(null); } if (stream.Count == 0) { return(null); } if (stream.NextIsEndOfStream) { return(null); } LogicalLine line = null; try { if (stream.NextToken is IfStatementPrimitive) //if, else行 { return((LogicalLine)readIf(stream)); } if (stream.NextToken is McallFunctionPrimitive) //on行 { return((LogicalLine)readMcall(stream)); } if (stream.NextToken is OnEventFunctionPrimitive) { //on###行 if (stream.NextNextTokenIsGotoFunction) //goto/gosubがないなら { return((LogicalLine)readOnEvent(stream)); } else { return((LogicalLine)readCommand(stream)); } } if (stream.NextToken is OnFunctionPrimitive) //on行 { return((LogicalLine)readOn(stream)); } if (stream.NextToken is FunctionPrimitive) //その他の関数 { return((LogicalLine)readCommand(stream)); } if (stream.NextToken is VariablePrimitive) //代入行 { return((LogicalLine)readAssignment(stream)); } } //ここでHspLogicalLineExceptionをcatchする。他のところでは行ってはならない catch (HspLogicalLineException e) { line = new UnknownLine(stream.Primitives); line.AddError(e.Message); return(line); } line = new UnknownLine(stream.Primitives); line.AddError("?行:先頭の単語が解釈できない"); return(line); }