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()); }
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); }