Example #1
0
        private OpCodeKb(OpCodeFamilyKb familyKb, OpCode? opcode)
        {
            FamilyKb = familyKb;
            _opCode = opcode;

            Tags = new HashSet<String>();
            Meta = new Dictionary<String, String>();
            Fields = new Dictionary<String, FieldSpec>();
            Props = new Dictionary<String, PropertySpec>();
            Prefixes = new Dictionary<String, PrefixSpec>();
        }
Example #2
0
        private OpCodeKb(OpCodeFamilyKb familyKb, OpCode?opcode)
        {
            FamilyKb = familyKb;
            _opCode  = opcode;

            Tags     = new HashSet <String>();
            Meta     = new Dictionary <String, String>();
            Fields   = new Dictionary <String, FieldSpec>();
            Props    = new Dictionary <String, PropertySpec>();
            Prefixes = new Dictionary <String, PrefixSpec>();
        }
Example #3
0
 public OpCodeKb(OpCodeFamilyKb familyKb, OpCode opcode)
     : this(familyKb, (OpCode?)opcode)
 {
 }
Example #4
0
 public OpCodeKb(OpCodeFamilyKb familyKb)
     : this(familyKb, null)
 {
 }
        private PropertySpec UniteSubSpecsForProp(OpCodeFamilyKb fkb, String pname)
        {
            // 1. Create a property spec
            var pspecs = fkb.SubSpecs.ToDictionary(kvp => kvp.Key, kvp => 
                kvp.Value.Props.Values.SingleOrDefault(f => f.Name == pname) ?? new PropertySpec{Name = pname});
            var united = new PropertySpec();
            united.Name = pname;

            // 2. Find out an unified type (it should be specified at least once and every time the same)
            var ptypes = pspecs.Values.Select(v => v.Type);
            var ptype = ptypes.Where(v => v != null).Distinct().Single();
            united.Type = ptype;

            // 3. Normalize getters (setters ain't supported) for every opcode (replace null with default(T))
            foreach (var spec in pspecs.Values)
            {
                var init = spec.Getter;
                if (init.IsNullOrEmpty())
                {
                    spec.Getter = "default(" + ptype.GetCSharpRef(ToCSharpOptions.ForCodegen) + ")";
                }
            }

            // 4. Now assemble all initializers into a single language construct (setters ain't supported)!
            var getters = pspecs.Where(kvp => kvp.Value.Getter.IsNeitherNullNorEmpty())
                .GroupBy(kvp => kvp.Value.Getter, kvp => kvp.Key);
            (getters.Count() >= 1).AssertTrue();

            // 4.1. There's only 1 possible opcode => 1 possible getter
            // or maybe all getters for different opcodes are the same.
            // This means that we can reuse its expression and just return it. EZ!
            if (getters.Count() == 1)
            {
                var getterCode = getters.Single().Key;
                if (!getterCode.EndsWith(";")) getterCode = getterCode + ";";
                if (!getterCode.StartsWith("return") && !getterCode.Contains(Environment.NewLine)) 
                    getterCode = "return " + getterCode;
                united.Getter = getterCode;
            }
            // 4.2. There are multiple distinct getters
            // Thus, we're forced to implement a switch depending on the opcode.
            // Default will crash the switch since we're unprepared to it.
            else
            {
                var getter = new StringBuilder();
                getter.AppendLine(String.Format("switch(({0})OpSpec.OpCode.Value)",
                    typeof(UInt16).GetCSharpRef(ToCSharpOptions.ForCodegen)));
                getter.AppendLine("{");

                foreach (var getterClause in getters)
                {
                    foreach (var opcode in getterClause)
                    {
                        var @case = "case " + opcode.GetCSharpByteSequence() + ":";
                        @case = @case + " //" + opcode.Name;
                        getter.AppendLine(@case.Indent());
                    }

                    var getterCode = getterClause.Key;
                    if (!getterCode.EndsWith(";")) getterCode = getterCode + ";";
                    if (!getterCode.StartsWith("return") && !getterCode.Contains(Environment.NewLine)) 
                        getterCode = "return " + getterCode;
                    getter.AppendLine(getterCode.Indent().Indent());
                }

                getter.AppendLine("default:".Indent());
                var throwOnUnknown = String.Format("throw {0}.Fail();",
                    typeof(AssertionHelper).GetCSharpRef(ToCSharpOptions.ForCodegen));
                getter.AppendLine(throwOnUnknown.Indent().Indent());

                getter.AppendLine("}");
                united.Getter = getter.ToString();
            }

            // 5. Setters ain't supported since they weren't necessary
            var setters = pspecs.Where(kvp => kvp.Value.Setter.IsNeitherNullNorEmpty())
                .GroupBy(kvp => kvp.Value.Setter, kvp => kvp.Key);
            setters.AssertCount(0);

            return united;
        }
        private FieldSpec UniteSubSpecsForField(OpCodeFamilyKb fkb, String fname)
        {
            // 1. Create a field spec
            var fspecs = fkb.SubSpecs.ToDictionary(kvp => kvp.Key, kvp => 
                kvp.Value.Fields.Values.SingleOrDefault(f => f.Name == fname) ?? new FieldSpec{Name = fname});
            var united = new FieldSpec();
            united.Name = fname;

            // 2. Find out an unified type (it should be specified at least once and every time the same)
            var ftypes = fspecs.Values.Select(v => v.Type);
            var ftype = ftypes.Where(v => v != null).Distinct().Single();
            united.Type = ftype;

            // 3. Normalize initializers for every opcode (replace null with default(T))
            foreach (var spec in fspecs.Values)
            {
                var init = spec.Initializer;
                if (init.IsNullOrEmpty())
                {
                    spec.Initializer = "default(" + ftype.GetCSharpRef(ToCSharpOptions.ForCodegen) + ")";
                }
            }

            // 4. Now assemble all initializers into a single language construct
            var initGroups = fspecs.Where(kvp => kvp.Value.Initializer.IsNeitherNullNorEmpty())
                .GroupBy(kvp => kvp.Value.Initializer, kvp => kvp.Key);
            (initGroups.Count() >= 1).AssertTrue();

            // 4.1. There's only 1 possible opcode => 1 possible initializer
            // or maybe all initializers for different opcodes are the same.
            // This means that we can reuse its expression and assign the value to the field. EZ!
            if (initGroups.Count() == 1)
            {
                var initCode = initGroups.Single().Key;
                if (!initCode.EndsWith(";")) initCode = initCode + ";";
                initCode = fname + " = " + initCode;
                united.Initializer = (initCode + Environment.NewLine);
            }
            // 4.2. There are multiple distinct initializers
            // Thus, we're forced to implement a switch depending on the opcode.
            // Default will crash the switch since we're unprepared to it.
            else
            {
                var init = new StringBuilder();
                init.AppendLine(String.Format("switch(({0})OpSpec.OpCode.Value)",
                    typeof(UInt16).GetCSharpRef(ToCSharpOptions.ForCodegen)));
                init.AppendLine("{");

                foreach (var initGroup in initGroups)
                {
                    foreach (var opcode in initGroup)
                    {
                        var @case = "case " + opcode.GetCSharpByteSequence() + ":";
                        @case = @case + " //" + opcode.Name;
                        init.AppendLine(@case.Indent());
                    }

                    var initCode = initGroup.Key;
                    if (!initCode.EndsWith(";")) initCode = initCode + ";";
                    initCode = fname + " = " + initCode;
                    init.AppendLine(initCode.Indent().Indent());
                    init.AppendLine("break;".Indent().Indent());
                }

                init.AppendLine("default:".Indent());
                var throwOnUnknown = String.Format("throw {0}.Fail();", 
                    typeof(AssertionHelper).GetCSharpRef(ToCSharpOptions.ForCodegen));
                init.AppendLine(throwOnUnknown.Indent().Indent());

                init.AppendLine("}");
                united.Initializer = init.ToString();
            }

            return united;
        }
Example #7
0
 public OpCodeKb(OpCodeFamilyKb familyKb, OpCode opcode)
     : this(familyKb, (OpCode?)opcode)
 {
 }
Example #8
0
 public OpCodeKb(OpCodeFamilyKb familyKb)
     : this(familyKb, null)
 {
 }