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 _setVariable(NakoNodeVariable node) { // _let() で処理されるのでここでは何もしない }
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); }
//> _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; }
//> _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; }
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; }
//> _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; }
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; }