//Compiles record literal private ExprData CompileRecord(ElaRecordLiteral p, LabelMap map, Hints hints) { AddLinePragma(p); cw.Emit(Op.Newrec, p.Fields.Count); for (var i = 0; i < p.Fields.Count; i++) { var f = p.Fields[i]; CompileExpression(f.FieldValue, map, Hints.None, f); cw.Emit(Op.Pushstr, AddString(f.FieldName)); cw.Emit(Op.Reccons, i); } if ((hints & Hints.Left) == Hints.Left) AddValueNotUsed(p); return new ExprData(DataKind.VarType, (Int32)ElaTypeCode.Record); }
//Compile a record pattern in the form: {fieldName=pat,..}. Here we don't check the //type of an expression on the top of the stack - in a case if try to match a non-record //using this pattern the whole match would fail on Pushfld operation. private void CompileRecordPattern(int sysVar, ElaRecordLiteral rec, Label failLab, bool allowBang) { //Loops through all record fields for (var i = 0; i < rec.Fields.Count; i++) { var fld = rec.Fields[i]; var addr = AddVariable(); var si = AddString(fld.FieldName); PushVar(sysVar); cw.Emit(Op.Pushstr, si); cw.Emit(Op.Hasfld); cw.Emit(Op.Brfalse, failLab); PushVar(sysVar); cw.Emit(Op.Pushstr, si); cw.Emit(Op.Pushfld); PopVar(addr); //We obtain a value of field, now we need to match it using a pattern in //a field value (it could be a name reference or a non-irrefutable pattern). CompilePattern(addr, fld.FieldValue, failLab, allowBang, false /*forceStrict*/); } }
void RecordLiteral(out ElaExpression exp) { exp = null; var fld = default(ElaFieldDeclaration); Expect(19); var rec = new ElaRecordLiteral(t); exp = rec; RecordField(out fld); rec.Fields.Add(fld); while (la.kind == 56) { Get(); RecordField(out fld); rec.Fields.Add(fld); } Expect(20); }