diff --git a/src/lexer.cpp b/src/lexer.cpp index fcf1bcc..d5930fa 100644 --- a/src/lexer.cpp +++ b/src/lexer.cpp @@ -122,10 +122,6 @@ void Lexer::identifier() { addToken(TOK_PUB, text); } else if (text == "import") { addToken(TOK_IMPORT, text); - } else if (text == "and") { - addToken(TOK_AND, text); - } else if (text == "or") { - addToken(TOK_OR, text); } else if (text == "tfn") { addToken(TOK_TFN, text); } else if (text == "struct") { @@ -541,10 +537,18 @@ std::vector Lexer::scanTokens() { addToken(TOK_PERCENT, "%"); break; case '&': - addToken(TOK_AMP, "&"); + if (match('&')) { + addToken(TOK_AND, "&&"); + } else { + addToken(TOK_AMP, "&"); + } break; case '|': - addToken(TOK_PIPE, "|"); + if (match('|')) { + addToken(TOK_OR, "||"); + } else { + addToken(TOK_PIPE, "|"); + } break; case '^': addToken(TOK_CARET, "^"); diff --git a/src/token.h b/src/token.h index 720aa67..5b6586e 100644 --- a/src/token.h +++ b/src/token.h @@ -55,8 +55,8 @@ enum TokenType { TOK_PUB, // pub keyword (visible to Jam modules, like Zig) TOK_IMPORT, // import keyword TOK_DOT, // . for member access - TOK_AND, // and (logical AND) - TOK_OR, // or (logical OR) + TOK_AND, // && (logical AND, short-circuit) + TOK_OR, // || (logical OR, short-circuit) TOK_NOT, // ! (logical NOT) TOK_TFN, // tfn keyword (test function) TOK_STRUCT, // struct keyword diff --git a/tests/unit/test_bool.jam b/tests/unit/test_bool.jam index 425ba20..89531fe 100644 --- a/tests/unit/test_bool.jam +++ b/tests/unit/test_bool.jam @@ -13,11 +13,11 @@ fn bool_not(a: bool) bool { } fn bool_and(a: bool, b: bool) bool { - return a and b; + return a && b; } fn bool_or(a: bool, b: bool) bool { - return a or b; + return a || b; } fn bool_eq(a: bool, b: bool) bool { diff --git a/tests/unit/test_short_circuit.jam b/tests/unit/test_short_circuit.jam index ab22937..bced8b5 100644 --- a/tests/unit/test_short_circuit.jam +++ b/tests/unit/test_short_circuit.jam @@ -1,41 +1,41 @@ -// Test short-circuit evaluation for 'and' and 'or' operators +// Test short-circuit evaluation for `&&` and `||` operators. -// Test 'and' short-circuit: if first is false, second is not evaluated +// `&&` short-circuit: if first is false, second is not evaluated. fn test_and_short_circuit(a: bool, b: bool) bool { - return a and b; + return a && b; } -// Test 'or' short-circuit: if first is true, second is not evaluated +// `||` short-circuit: if first is true, second is not evaluated. fn test_or_short_circuit(a: bool, b: bool) bool { - return a or b; + return a || b; } -// Nested short-circuit: (a and b) or c +// Nested short-circuit: (a && b) || c fn test_nested_and_or(a: bool, b: bool, c: bool) bool { - return (a and b) or c; + return (a && b) || c; } -// Nested short-circuit: (a or b) and c +// Nested short-circuit: (a || b) && c fn test_nested_or_and(a: bool, b: bool, c: bool) bool { - return (a or b) and c; + return (a || b) && c; } -// Chain: a and b and c +// Chain: a && b && c fn test_chain_and(a: bool, b: bool, c: bool) bool { - return a and b and c; + return a && b && c; } -// Chain: a or b or c +// Chain: a || b || c fn test_chain_or(a: bool, b: bool, c: bool) bool { - return a or b or c; + return a || b || c; } -// Mixed with not: !a and b +// Mixed with not: !a && b fn test_not_and(a: bool, b: bool) bool { - return !a and b; + return !a && b; } -// Mixed with not: a or !b +// Mixed with not: a || !b fn test_or_not(a: bool, b: bool) bool { - return a or !b; + return a || !b; }