Skip to content

Commit

Permalink
Merge pull request #33 from quephird/add_modulus_operator
Browse files Browse the repository at this point in the history
Add modulus operator
  • Loading branch information
quephird committed Mar 25, 2024
2 parents 4982e24 + 54acfc4 commit 3ad7b51
Show file tree
Hide file tree
Showing 7 changed files with 38 additions and 3 deletions.
2 changes: 2 additions & 0 deletions slox/Interpreter.swift
Expand Up @@ -395,6 +395,8 @@ class Interpreter {
return .int(leftNumber * rightNumber)
case .slash:
return .int(leftNumber / rightNumber)
case .modulus:
return .int(leftNumber % rightNumber)
case .greater:
return .boolean(leftNumber > rightNumber)
case .greaterEqual:
Expand Down
4 changes: 2 additions & 2 deletions slox/Parser.swift
Expand Up @@ -404,7 +404,7 @@ struct Parser {
// equality → comparison ( ( "!=" | "==" ) comparison )* ;
// comparison → term ( ( ">" | ">=" | "<" | "<=" ) term )* ;
// term → factor ( ( "-" | "+" ) factor )* ;
// factor → unary ( ( "/" | "*" ) unary )* ;
// factor → unary ( ( "/" | "*" | "%" ) unary )* ;
// unary → ( "!" | "-" ) unary
// | postfix ;
// postfix → primary ( "(" arguments? ")" | "." IDENTIFIER | "[" logicOr "]" )* ;
Expand Down Expand Up @@ -503,7 +503,7 @@ struct Parser {
mutating private func parseFactor() throws -> Expression {
var expr = try parseUnary()

while currentTokenMatchesAny(types: [.slash, .star]) {
while currentTokenMatchesAny(types: [.slash, .star, .modulus]) {
let oper = previousToken
let rightExpr = try parseUnary()
expr = .binary(expr, oper, rightExpr)
Expand Down
2 changes: 2 additions & 0 deletions slox/Scanner.swift
Expand Up @@ -82,6 +82,8 @@ struct Scanner {
handleSingleCharacterLexeme(type: .semicolon)
case "*":
handleSingleCharacterLexeme(type: .star)
case "%":
handleSingleCharacterLexeme(type: .modulus)
case "/":
handleSlash()

Expand Down
1 change: 1 addition & 0 deletions slox/TokenType.swift
Expand Up @@ -20,6 +20,7 @@ enum TokenType: Equatable {
case star
case leftBracket
case rightBracket
case modulus

// One of two character tokens
case bang
Expand Down
8 changes: 8 additions & 0 deletions sloxTests/InterpreterTests.swift
Expand Up @@ -74,6 +74,14 @@ final class InterpreterTests: XCTestCase {
XCTAssertEqual(actual, expected)
}

func testInterpretBinaryExpressionInvolvingModulusOperator() throws {
let input = "8 % 3"
let interpreter = Interpreter()
let actual = try interpreter.interpretRepl(source: input)!
let expected: LoxValue = .int(2)
XCTAssertEqual(actual, expected)
}

func testInterpretStringlyBinaryExpression() throws {
let input = "\"forty\" + \"-two\""
let interpreter = Interpreter()
Expand Down
21 changes: 21 additions & 0 deletions sloxTests/ParserTests.swift
Expand Up @@ -158,6 +158,27 @@ final class ParserTests: XCTestCase {
XCTAssertEqual(actual, expected)
}

func testParseFactorExpressionWithModulusOperator() throws {
let tokens: [Token] = [
Token(type: .int, lexeme: "5", line: 1),
Token(type: .modulus, lexeme: "%", line: 1),
Token(type: .int, lexeme: "3", line: 1),
Token(type: .semicolon, lexeme: ";", line: 1),
Token(type: .eof, lexeme: "", line: 1),
]
var parser = Parser(tokens: tokens)

let actual = try parser.parse()
let expected: [Statement] = [
.expression(
.binary(
.literal(.int(5)),
Token(type: .modulus, lexeme: "%", line: 1),
.literal(.int(3))))
]
XCTAssertEqual(actual, expected)
}

func testParseTermExpression() throws {
let tokens: [Token] = [
Token(type: .string, lexeme: "\"forty-\"", line: 1),
Expand Down
3 changes: 2 additions & 1 deletion sloxTests/ScannerTests.swift
Expand Up @@ -9,7 +9,7 @@ import XCTest

final class ScannerTests: XCTestCase {
func testScanningOfOneCharacterLexemes() throws {
let source = "( ) { } [ ] , . - + ; *"
let source = "( ) { } [ ] , . - + ; * %"
var scanner = Scanner(source: source)
let actual = try! scanner.scanTokens()
let expected: [Token] = [
Expand All @@ -25,6 +25,7 @@ final class ScannerTests: XCTestCase {
Token(type: .plus, lexeme: "+", line: 1),
Token(type: .semicolon, lexeme: ";", line: 1),
Token(type: .star, lexeme: "*", line: 1),
Token(type: .modulus, lexeme: "%", line: 1),
Token(type: .eof, lexeme: "", line: 1),
]

Expand Down

0 comments on commit 3ad7b51

Please sign in to comment.