// A map literal. private static void Map(Compiler c, bool allowAssignment) { // Load the Map class. int mapClassSymbol = c._parser.Module.Variables.FindIndex(v => v.Name == "Map"); c.EmitShortArg(Instruction.LoadModuleVar, mapClassSymbol); // Instantiate a new map. c.CallMethod(0, "<instantiate>"); // Compile the map elements. Each one is compiled to just invoke the // subscript setter on the map. if (c.Peek() != TokenType.RightBrace) { do { c.IgnoreNewlines(); // Push a copy of the map since the subscript call will consume it. c.Emit(Instruction.Dup); // The key. c.ParsePrecedence(false, Precedence.Primary); c.Consume(TokenType.Colon, "Expect ':' after map key."); // The value. c.Expression(); c.CallMethod(2, "[_]=(_)"); // Discard the result of the setter call. c.Emit(Instruction.Pop); } while (c.Match(TokenType.Comma)); } // Allow newlines before the closing '}'. c.IgnoreNewlines(); c.Consume(TokenType.RightBrace, "Expect '}' after map entries."); }
private static void InfixOp(Compiler c, bool allowAssignment) { GrammarRule rule = c.GetRule(c._parser.Previous.Type); // An infix operator cannot end an expression. c.IgnoreNewlines(); // Compile the right-hand side. c.ParsePrecedence(false, rule.Precedence + 1); // Call the operator method on the left-hand side. Signature signature = new Signature { Type = SignatureType.Method, Arity = 1, Name = rule.Name, Length = rule.Name.Length }; c.CallSignature(Instruction.Call0, signature); }
private static void and_(Compiler c, bool allowAssignment) { c.IgnoreNewlines(); // Skip the right argument if the left is false. int jump = c.EmitJump(Instruction.And); c.ParsePrecedence(false, Precedence.LogicalAnd); c.PatchJump(jump); }
private static void Conditional(Compiler c, bool allowAssignment) { // Ignore newline after '?'. c.IgnoreNewlines(); // Jump to the else branch if the condition is false. int ifJump = c.EmitJump(Instruction.JumpIf); // Compile the then branch. c.ParsePrecedence(allowAssignment, Precedence.Ternary); c.Consume(TokenType.Colon, "Expect ':' after then branch of conditional operator."); c.IgnoreNewlines(); // Jump over the else branch when the if branch is taken. int elseJump = c.EmitJump(Instruction.Jump); // Compile the else branch. c.PatchJump(ifJump); c.ParsePrecedence(allowAssignment, Precedence.Assignment); // Patch the jump over the else. c.PatchJump(elseJump); }
// Unary operators like `-foo`. private static void UnaryOp(Compiler c, bool allowAssignment) { GrammarRule rule = c.GetRule(c._parser.Previous.Type); c.IgnoreNewlines(); // Compile the argument. c.ParsePrecedence(false, Precedence.Unary + 1); // Call the operator method on the left-hand side. c.CallMethod(0, rule.Name); }