//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(map, 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*/); } }