private bool _throw() { //○○で|のエラー発生 TokenTry(); bool is_value = _value(); if (!Accept(NakoTokenType.THROW)) { TokenBack(); return(false); } TokenFinally(); NakoNodeThrow nt = new NakoNodeThrow(); nt.errorVarNo = localVar.GetIndex(NakoReservedWord.ERROR, true); // 変数「エラー値」の変数番号を取得 NakoNodeVariable v = new NakoNodeVariable(); v.varType = NakoVarType.Object; if (is_value) { v.value = new InvalidOperationException(); //TODO:set exception from value } else { v.value = new Exception(); } nt.exceptionNode = v; parentNode.AddChild(nt); tok.MoveNext(); return(true); }
private bool _return() { TokenTry(); bool is_value = _value(); if (!Accept(NakoTokenType.RETURN)) { TokenBack(); return(false); } TokenFinally(); if (is_value) { NakoNodeLet node = new NakoNodeLet(); NakoNodeVariable sore = new NakoNodeVariable(); sore.varNo = (int)0; sore.scope = NakoVariableScope.Global; node.VarNode = sore; NakoNodeLetValue valuenode = new NakoNodeLetValue(); while (calcStack.Count > 0) { valuenode.AddChild(calcStack.Shift()); } node.ValueNode = (NakoNode)valuenode; parentNode.AddChild(node); } parentNode.AddChild(new NakoNodeReturn()); tok.MoveNext(); return(true); }
//> _variable : WORD '[' VALUE ']' //> | WORD '\' //> | WORD ; private bool _variable() { if (!Accept(NakoTokenType.WORD)) { return(false); } // 変数アクセス NakoNodeVariable n = new NakoNodeVariable(); n.type = NakoNodeType.LD_VARIABLE; n.Token = tok.CurrentToken; string name = (string)tok.CurrentToken.Value; _variable__detectVariable(n, name); lastNode = n; tok.MoveNext(); // 要素へのアクセスがあるか if (Accept(NakoTokenType.BRACKETS_L) || Accept(NakoTokenType.YEN)) { _variable_elements(n); } calcStack.Push(n); return(true); }
//> _setVariable : WORD _variable_elements //> | WORD ; private bool _setVariable() { if (!Accept(NakoTokenType.WORD)) { return(false); } // 設定用変数の取得 NakoNodeVariable n = new NakoNodeVariable(); n.type = NakoNodeType.ST_VARIABLE; n.Token = tok.CurrentToken; // 変数アクセス string name = (string)tok.CurrentToken.Value; _variable__detectVariable(n, name); tok.MoveNext();// skip WORD // 要素へのアクセスがあるか if (Accept(NakoTokenType.BRACKETS_L) || Accept(NakoTokenType.YEN)) { // _value を読む前に setVariable のフラグをたてる flag_set_variable = true; _variable_elements(n); flag_set_variable = false; } lastNode = n; return(true); }
//> _for : WORD _value _value FOR _scope_or_statement //> ; private bool _for() { NakoToken tokVar = null; TokenTry(); // local variable if (!Accept(NakoTokenType.WORD)) { return(false); } tokVar = tok.CurrentToken; if (!(tokVar.Josi == "を" || tokVar.Josi == "で")) { return(false); } tok.MoveNext(); // get argument * 2 if (!_value()) { TokenBack(); return(false); } if (!_value()) { TokenBack(); return(false); } NakoNodeFor fornode = new NakoNodeFor(); NakoNodeVariable v = new NakoNodeVariable(); fornode.loopVar = v; v.scope = NakoVariableScope.Local; v.Token = tokVar; v.varNo = localVar.CreateVar(tokVar.Value); fornode.nodeTo = calcStack.Pop(); fornode.nodeFrom = calcStack.Pop(); if (!Accept(NakoTokenType.FOR)) { TokenBack(); return(false); } TokenFinally(); tok.MoveNext(); fornode.nodeBlocks = _scope_or_statement(); this.parentNode.AddChild(fornode); lastNode = fornode; return(true); }
//> _variable_elements : '[' _value ']' //> | '\' _value //> ; private bool _variable_elements(NakoNodeVariable n) { NakoToken firstT = tok.CurrentToken; // 配列アクセス? if (!Accept(NakoTokenType.BRACKETS_L) && !Accept(NakoTokenType.YEN)) { return(false); } NakoTokenType t; while (!tok.IsEOF()) { t = tok.CurrentTokenType; if (t == NakoTokenType.BRACKETS_L) { tok.MoveNext(); // skip ']' if (!_value()) { throw new NakoParserException("変数要素へのアクセスで要素式にエラー。", firstT); } if (!Accept(NakoTokenType.BRACKETS_R)) { throw new NakoParserException("変数要素へのアクセスで閉じ角カッコがありません。", firstT); } tok.MoveNext(); // skip ']' n.AddChild(calcStack.Pop()); } else // t == NakoTokenType.YEN { tok.MoveNext(); // skip '\' if (!_value_nojfunc()) { throw new NakoParserException("変数要素へのアクセスで要素式にエラー。", firstT); } n.AddChild(calcStack.Pop()); } // 引き続き、変数要素へのアクセスがあるかどうか if (Accept(NakoTokenType.BRACKETS_L)) { continue; } if (Accept(NakoTokenType.YEN)) { continue; } break; } return(true); }
private void _let(NakoNodeLet node) { NakoNodeVariable varNode = node.VarNode; NakoNode valueNode = node.ValueNode; // 配列要素があるか確認 if (!varNode.useElement) { // + 要素なしの代入処理 // - 代入する値を書き込んで... Write_r(valueNode); // - セットする NakoILCode st = new NakoILCode(); st.value = varNode.varNo; st.type = (varNode.scope == NakoVariableScope.Global) ? NakoILType.ST_GLOBAL : NakoILType.ST_LOCAL; result.Add(st); } else // 配列要素があるとき { // + 配列への代入処理 // - 基本となる変数をセット NakoILCode ldvar = new NakoILCode(); ldvar.value = varNode.varNo; ldvar.type = (varNode.scope == NakoVariableScope.Global) ? NakoILType.LD_GLOBAL_REF : NakoILType.LD_LOCAL_REF; result.Add(ldvar); // - アクセス要素をセット int count = varNode.Children.Count; for (int i = 0; i < count; i++) { NakoNode n = varNode.Children[i]; Write_r(n); // ノードの値 if (i < count - 1) { result.Add(new NakoILCode(NakoILType.LD_ELEM_REF)); // 要素 } else { // 値ノード Write_r(valueNode); addNewILCode(NakoILType.ST_ELEM); } } } }
private void _getVariable(NakoNodeVariable node) { NakoILCode ld = new NakoILCode(); if (!node.useElement) { // + 変数アクセス ld.type = (node.scope == NakoVariableScope.Global) ? NakoILType.LD_GLOBAL : NakoILType.LD_LOCAL; if (node.varBy == VarByType.ByRef) { _varBy_change_ref(ld); } ld.value = node.varNo; result.Add(ld); } else { // + 配列変数アクセス // - 変数 ld.type = (node.scope == NakoVariableScope.Global) ? NakoILType.LD_GLOBAL : NakoILType.LD_LOCAL; ld.value = node.varNo; result.Add(ld); // - 要素 NakoNodeList c = node.Children; for (int i = 0; i < c.Count; i++) { Write_r(c[i]); NakoILCode code = new NakoILCode(); /* * code.type = ((c.Count - 1) == i) * ? NakoILType.LD_ELEM * : NakoILType.LD_ELEM_REF; */ code.type = NakoILType.LD_ELEM; result.Add(code); } } }
private void _variable__detectVariable(NakoNodeVariable n, string name) { int varno; // local ? varno = localVar.GetIndex(name); if (varno >= 0) { n.scope = NakoVariableScope.Local; n.varNo = varno; return; } // global ? varno = globalVar.GetIndex(name); if (varno >= 0) { n.scope = NakoVariableScope.Global; n.varNo = varno; return; } // Create variable n.scope = NakoVariableScope.Global; n.varNo = globalVar.CreateVar(name); }
private void _setVariable(NakoNodeVariable node) { // _let() で処理されるのでここでは何もしない }