Beispiel #1
0
        private Node NewNodeIdent(LVar lvar)
        {
            var node = new Node();

            node.Kind   = NodeKind.Lvar;
            node.Offset = lvar.Offset;
            node.LVar   = lvar;
            return(node);
        }
Beispiel #2
0
        private void CreateLVars(List <Token> tokenList, List <Token> argumentTokens, List <LVar> lVars)
        {
            var offset = 0;

            // 引数トークンから引数のリストを作成
            var argIndex = 0;

            for (var i = 0; i < argumentTokens.Count;)
            {
                // 引数トークンの形式は決まっている。最初はタイプのはず。
                var typeToken = argumentTokens[i];
                if (typeToken.Kind != TokenKind.Type)
                {
                    throw new ArgumentException($"Invalid ArgumentToken:{typeToken} ArgumentTokenIndex:{i}");
                }
                i++;

                // "*"の数を取得
                var pointerCount = 0;
                for (; "*".Equals(argumentTokens[i + pointerCount].Str); pointerCount++)
                {
                    ;
                }
                i += pointerCount;

                // 次のトークンはidentのはず
                var identToken = argumentTokens[i];
                i++;

                offset += 8;
                var lvar = new LVar
                {
                    Name         = identToken.Str,
                    Kind         = typeToken.TypeKind,
                    Offset       = offset,
                    PointerCount = pointerCount,
                    ArraySize    = 0,
                    ArgIndex     = argIndex,
                };

                lVars.Add(lvar);
                argIndex++;

                // 次のトークンがあるとしたら","だが、ここで終わりの可能性もある
                var commaToken = i < argumentTokens.Count ? argumentTokens[i] : null;
                if (commaToken == null)
                {
                    break;
                }
                if (!commaToken.Str.Equals(","))
                {
                    throw new ArgumentException($"Not comma token:{commaToken} index:{i}");
                }
                i++;
            }

            for (var i = 0; i < tokenList.Count;)
            {
                var typeToken = tokenList[i];
                i++;
                if (typeToken.Kind != TokenKind.Type)
                {
                    continue;
                }

                // "*"の数を取得
                var pointerCount = 0;
                for (; "*".Equals(tokenList[i + pointerCount].Str); pointerCount++)
                {
                    ;
                }
                i += pointerCount;

                // 次のトークンはidentのはず
                var identToken = tokenList[i];
                i++;

                // さらに次のトークンが「(」の場合は関数宣言なのでスキップ
                // 「[」の場合は配列
                var nextToken = tokenList[i];
                i++;
                if (nextToken.Str.Equals("("))
                {
                    continue;
                }

                var arraySize = 0;
                if (nextToken.Str.Equals("["))
                {
                    // 配列として定義されている場合は、配列の数を取得してpointerCountを加算
                    // 配列をポインタとして考えるため
                    var numToken = tokenList[i];
                    i++;
                    arraySize = numToken.Value;
                    pointerCount++;

                    // 次は閉じカッコのはず(カッコの中の計算は今の所許容していない)
                    var endBracketToken = tokenList[i];
                    if (!endBracketToken.Str.Equals("]"))
                    {
                        throw new ArgumentException($"Not end bracket token:{endBracketToken} index:{i}");
                    }
                    i++;
                }

                // 同じ変数名があった場合はException
                if (lVars.Exists((lvar) => lvar.Name == identToken.Str))
                {
                    throw new ArgumentException($"Duplicate Identifier:{identToken.Str}");
                }

                // 配列の場合は、変数のアドレスを設定した後で配列の要素分だけオフセットを加算する必要がある
                offset += 8 * arraySize;

                offset += 8;
                var lvar = new LVar
                {
                    Name         = identToken.Str,
                    Kind         = typeToken.TypeKind,
                    Offset       = offset,
                    PointerCount = pointerCount,
                    ArraySize    = arraySize,
                    ArgIndex     = -1,
                };

                lVars.Add(lvar);
            }
        }