Beispiel #1
0
        static ZilObject MakeDefstructAccessMacro([NotNull] Context ctx, [NotNull] ZilAtom structName, DefStructDefaults defaults,
                                                  DefStructField field)
        {
            // {0} = field name
            // {1} = struct name
            // {2} = PUT atom
            // {3} = NTH atom
            // {4} = offset
            // {5} = field decl
            const string SFullCheckTemplate  = @"
<DEFMAC {0} ('S ""OPT"" 'NV)
    <COND (<ASSIGNED? NV>
           <FORM {2} <CHTYPE [.S {1}] ADECL> {4} <CHTYPE [.NV <QUOTE {5}>] ADECL>>)
          (T
           <CHTYPE [<FORM {3} <CHTYPE [.S {1}] ADECL> {4}> <QUOTE {5}>] ADECL>)>>
";
            const string SFieldCheckTemplate = @"
<DEFMAC {0} ('S ""OPT"" 'NV)
    <COND (<ASSIGNED? NV>
           <FORM {2} .S {4} <CHTYPE [.NV <QUOTE {5}>] ADECL>>)
          (T
           <CHTYPE [<FORM {3} .S {4}> <QUOTE {5}>] ADECL>)>>
";
            const string SNoCheckTemplate    = @"
<DEFMAC {0} ('S ""OPT"" 'NV)
    <COND (<ASSIGNED? NV>
           <FORM {2} .S {4} .NV>)
          (T
           <FORM {3} .S {4}>)>>
";

            string template;

            if (defaults.SuppressDecl)
            {
                template = SNoCheckTemplate;
            }
            else if (defaults.SuppressType)
            {
                template = SFieldCheckTemplate;
            }
            else
            {
                template = SFullCheckTemplate;
            }

            return(Program.Parse(
                       ctx,
                       template,
                       field.Name,
                       structName,
                       field.PutFunc,
                       field.NthFunc,
                       new ZilFix(field.Offset),
                       field.Decl)
                   .Single());
        }
Beispiel #2
0
        static DefStructField ParseDefStructField(DefStructDefaults defaults, ref int offset, DefStructParams.FieldSpecList fieldSpec)
        {
            var result = new DefStructField
            {
                Decl    = fieldSpec.Decl,
                Name    = fieldSpec.Name,
                NthFunc = defaults.NthFunc,
                Offset  = offset,
                PutFunc = defaults.PutFunc
            };

            bool gotDefault = false, gotOffset = false;

            foreach (var part in fieldSpec.Parts)
            {
                switch (part)
                {
                case DefStructParams.AtomFieldSequence af:
                    switch (af.ClauseType)
                    {
                    case StdAtom.NTH:
                        result.NthFunc = af.Atom;
                        break;

                    case StdAtom.PUT:
                        result.PutFunc = af.Atom;
                        break;

                    default:
                        throw UnhandledCaseException.FromEnum(af.ClauseType, "atom clause type");
                    }
                    break;

                case DefStructParams.FixFieldSequence ff:
                    switch (ff.ClauseType)
                    {
                    case StdAtom.OFFSET:
                        result.Offset = ff.Fix;
                        gotOffset     = true;
                        break;

                    default:
                        throw UnhandledCaseException.FromEnum(ff.ClauseType, "FIX clause type");
                    }
                    break;

                case DefStructParams.NullaryFieldSequence nf:
                    switch (nf.ClauseType)
                    {
                    case StdAtom.NONE:
                        if (gotDefault)
                        {
                            throw new InterpreterError(InterpreterMessages._0_NONE_Is_Not_Allowed_After_A_Default_Field_Value, "DEFSTRUCT");
                        }
                        result.NoDefault = true;
                        gotDefault       = true;
                        break;

                    default:
                        throw UnhandledCaseException.FromEnum(nf.ClauseType, "nullary clause type");
                    }
                    break;

                case ZilObject zo when !gotDefault:
                    result.Default = zo;
                    gotDefault     = true;
                    break;

                default:
                    throw new InterpreterError(InterpreterMessages._0_Unrecognized_1_2, "DEFSTRUCT", "object in field definition", part);
                }
            }

            if (!gotOffset)
            {
                offset++;
            }

            return(result);
        }