static IrOperand ParseOperand(MfNode node) { return(new IrOperand { Name = node.Value, Type = ParseType(node[0]) }); }
static IrBlock ParseBlock(MfNode node) { return(new IrBlock { Name = node.Value, Instructions = node.Select(ParseInstruction).ToArray() }); }
public static IrModule Parse(string code) { var cur = new MfNode(); var stack = new Stack <MfNode>(); var tokens = Tokenize(code).ToList(); for (var i = 0; i < tokens.Count;) { if (tokens[i] == "$$end") { i++; cur = stack.Pop(); } else { var next = new MfNode { Name = tokens[i++], Value = tokens[i++] }; stack.Push(cur); cur.Add(next); cur = next; } } return(new IrModule { Functions = cur.Select(ParseFunction).ToArray() }); }
static IrFunction ParseFunction(MfNode node) { var types = node.Where(x => x.Name == "type").Select(ParseType).ToList(); Debug.Assert(types.Count > 0); return(new IrFunction { Name = node.Value, ReturnType = types[0], ParameterTypes = types.Skip(1).ToArray(), Blocks = node.Where(x => x.Name == "block").Select(ParseBlock).ToArray() }); }
static IrInst ParseInstruction(MfNode node) { switch (node.Value) { case "alloca": return(new AllocaInst { Output = ParseOperand(node[0]), AllocationRank = ParseOperand(node[2]), AllocationType = ParseType(node[1]) }); case "binary": var operands = node.Where(x => x.Name == "operand").ToList(); var flags = BinaryFlags.None; foreach (var elem in node) { if (elem.Name == "flag" && elem.Value == "nsw") { flags |= BinaryFlags.Nsw; } else if (elem.Name == "flag" && elem.Value == "nuw") { flags |= BinaryFlags.Nuw; } } return(new BinaryInst { Op = node[0].Value, Flags = flags, Output = ParseOperand(operands[0]), A = ParseOperand(operands[1]), B = ParseOperand(operands[2]) }); case "bitcast": return(new BitcastInst { Output = ParseOperand(node[0]), Value = ParseOperand(node[1]) }); case "br": return(new BrInst { Target = node[0].Value }); case "br.if": return(new BrIfInst { Condition = ParseOperand(node[0]), If = node[1].Value, Else = node[2].Value }); case "call": return(new CallInst { Output = ParseOperand(node[0]), Target = node[1].Value, Parameters = node.Skip(2).Select(ParseOperand).ToArray() }); case "icmp": return(new IcmpInst { Predicate = node[0].Value, Output = ParseOperand(node[1]), A = ParseOperand(node[2]), B = ParseOperand(node[3]) }); case "load": return(new LoadInst { Output = ParseOperand(node[0]), Pointer = ParseOperand(node[1]) }); case "phi": return(new PhiInst { Output = ParseOperand(node[0]), Incoming = node.Skip(1).Select(x => (x.Name, x.Value)).ToArray() });