コード例 #1
0
ファイル: Compiler.cs プロジェクト: tokiwoousaka/OSETools
        /// <summary>
        /// 文を評価しEmitします
        /// </summary>
        /// <param name="e">Statement</param>
        void CompileStmt(IStmt e)
        {
            // インラインアセンブラ
            // {name} でレジスタ値orラベル値を挿入可能
            if (e.GetType() == typeof(Inline))
            {
                var inline = (Inline)e;
                gval.Concat(lval).Concat(lfunc).ToArray().ForEach(x => inline.Text = inline.Text.Replace("{" + x.Key + "}", x.Value.ToString("X2")));
                gfunc.ToArray().ForEach(x => inline.Text = inline.Text.Replace("{" + x.Key + "}", BitConverter.GetBytes(x.Value).Reverse().JoinToString("X2")));
                var parse = inline.Text.Where(char.IsLetterOrDigit).JoinToString().Split(2);
                ose.Emit(parse.Select(x => byte.Parse(x, System.Globalization.NumberStyles.HexNumber)).ToArray());
            }

            // 宣言、ロックするだけ
            else if (e.GetType() == typeof(Declare))
            {
                var dec      = (Declare)e;
                var register = (dec.Type.GetType() == typeof(IntType) ? ose.LocalRegister : ose.LocalPegister).Lock();
                (dec.Type.GetType() == typeof(IntType) ? lval : lfunc).Add(dec.Identity, register);
                FulynOption.DebugWrite("local register " + dec.Identity + ":" + register.ToString("X2"));
            }

            // 代入
            else if (e.GetType() == typeof(Subst))
            {
                var sub   = (Subst)e;
                var regs  = sub.Expr.Type.GetType() == typeof(IntType) ? lval : lfunc;
                var added = false;

                // 存在しなかった場合はロック
                if (!gval.Concat(lval).Any(x => x.Key == sub.Identity))
                {
                    var isint    = sub.Expr.Type.GetType() == typeof(IntType);
                    var register = (isint ? ose.LocalRegister : ose.LocalPegister).Lock();
                    regs.Add(sub.Identity, register);
                    FulynOption.DebugWrite("local register " + sub.Identity + ":" + register.ToString("X2"));
                    added = true;
                }
                CompileExpr(sub.Expr, returnto: (added ? regs : gval.Concat(lval).ToDictionary(_ => _.Key, _ => _.Value))[sub.Identity]);

                // $だったらgoto funcend
                if (sub.Identity == "$")
                {
                    ose.EmitMacro(Macro.Goto, new MacroValues(to => funcend));
                }
            }
        }