// This should make a decision between // MultOp or Factor private Node TermP(Node factor) { string first = "* / and"; string follow = "+ - or eq neq lt gt leq geq ] ) ; ,"; this.SkipErrors(first, follow); var lookaheadToken = this.TokenStream.Peek(); string lookahead = lookaheadToken.AToCCFormat(); if (first.HasToken(lookahead)) { this.ApplyDerivation("termP -> multOp factor termP"); var term = new MultOp(lookaheadToken.SourceLocation); string op = MultOp(); Node nextTerm = Factor(); Node trailingTerm = TermP(nextTerm); term.LHS = factor; term.Operator = op; term.RHS = trailingTerm; return(term); } if (follow.HasToken(lookahead)) { this.ApplyDerivation("termP -> EPSILON"); return(factor); } return(null); }
public override void Visit(MultOp multOp) { if (multOp.RHS is Node rhs) { if (multOp.LHS is Node lhs) { if (lhs.SemanticalType != rhs.SemanticalType) { ErrorManager.Add($"Inconsistent types: Cannot perform {lhs.SemanticalType} {multOp.Operator} {rhs.SemanticalType}", multOp.Location); } } multOp.SemanticalType = rhs.SemanticalType; } else { ErrorManager.Add("There is no RHS for this multiplication operation.", multOp.Location); } }
public override void Visit(MultOp multOp) { this.AddToStack(multOp); }
public override void Visit(MultOp multOp) { multOp.NodeMemorySize = Sizes[multOp.SemanticalType]; }
public virtual void Visit(MultOp multOp) { }
public override void Visit(MultOp multOp) { string instruction = string.Empty; switch (multOp.Operator) { case "*": instruction = "mul"; break; case "/": instruction = "div"; break; case "and": instruction = "and"; break; } string floatPowerInstruction = instruction == "mul" ? "add" : "sub"; if (multOp.SemanticalType == "int" || instruction == "and") { this.Load(multOp.LHS, "r2"); this.Load(multOp.RHS, "r3"); InstructionStream.Add(new string[] { $"{instruction} r1, r2, r3", $"sw {multOp.stackOffset}(r14), r1" }, $"Calculating {multOp.ToString()}"); return; } this.Load(multOp.LHS, "r2", "r3"); this.Load(multOp.RHS, "r4", "r5"); InstructionStream.Add(new string[] { $"pas1{GetTag(multOp)} cgt r1, r3, r5 % While r3 > r5, shift it until they're equal", $"bz r1, pas2{GetTag(multOp)} % Otherwise, continue.", "addi r5, r5, 1", "divi r4, r4, 10", $"j pas1{GetTag(multOp)}", $"pas2{GetTag(multOp)} cgt r1, r5, r3 % While r5 > r3, shift it until they're equal", $"bz r1, pas3{GetTag(multOp)} % Otherwise, continue.", "addi r3, r3, 1", "divi r2, r2, 10", $"j pas2{GetTag(multOp)}", $"pas3{GetTag(multOp)} divi r2, r2, 10000 % Make sure it's in the right for for performing multiplication", $"addi r3, r3, 4", $"divi r4, r4, 10000", $"addi r5, r5, 4", $"{floatPowerInstruction} r3, r3, r5", $"{instruction} r2, r2, r4 % Perform {multOp}", "addi r6, r0, 10000 % Make 100,000,000", "muli r6, r6, 10000", "cgei r7, r2, 0 % If we're dealing with a positive number, store the sign.", $"bnz r7, pas4{GetTag(multOp)}", $"addi r7, r0, -1 % Otherwise, it's negative. Store the sign.", $"muli r2, r2, -1 % Also make r2 positive for now.", $"pas4{GetTag(multOp)} clt r1, r2, r6 % While realval < 100,000", $"bz r1, pas5{GetTag(multOp)}", "ceqi r1, r2, 0 % And also not 0", $"bnz r1, pas5{GetTag(multOp)}", "subi r3, r3, 1 % Shift it.", "muli r2, r2, 10", $"j pas4{GetTag(multOp)}", $"pas5{GetTag(multOp)} muli r6, r6, 10 % Make 1,000,000,000", $"pas6{GetTag(multOp)} cge r1, r2, r6 % While realval >= 1,000,000,000", $"bz r1, pas7{GetTag(multOp)}", "ceqi r1, r2, 0 % And also not 0", $"bnz r1, pas7{GetTag(multOp)}", "addi r3, r3, 1 % Shift it.", "divi r2, r2, 10", $"j pas6{GetTag(multOp)}", $"pas7{GetTag(multOp)} mul r2, r2, r7 % Apply the sign.", $"sw {multOp.stackOffset}(r14), r2 % Store the new float val", $"sw {multOp.stackOffset + 4}(r14), r3" }, $"Calculating {multOp}"); }
///<summary> ///Prints multiplication ///</summary> ///<param name="multOp">Multiplication operator that represents a tree of expressions</param> ///<returns> ///String to print ///</returns> string IVisitor <string> .visit(MultOp multOp) { return(new string("(" + multOp.left.acceptVisitor(this) + "*" + multOp.right.acceptVisitor(this) + ")")); }