diff --git a/compiler/src/parsing/lexer.mll b/compiler/src/parsing/lexer.mll index 55546f7c09..2d701c9ae5 100644 --- a/compiler/src/parsing/lexer.mll +++ b/compiler/src/parsing/lexer.mll @@ -191,6 +191,7 @@ rule token = parse | "}" { RBRACE } | "[" { LBRACK } | "]" { RBRACK } + | "^" { CARET } | "<" { LCARET } | ">" { RCARET } | "^" { CARET } @@ -202,7 +203,9 @@ rule token = parse | "%" { PERCENT } | "<=" { LESSEQ } | ">=" { GREATEREQ } + | "&" { AMP } | "&&" { AMPAMP } + | "|" { PIPE } | "||" { PIPEPIPE } | "!" { NOT } | '"' { read_dquote_str (Buffer.create 16) lexbuf } diff --git a/compiler/src/parsing/parser.dyp b/compiler/src/parsing/parser.dyp index 11ac630851..91d66cfbc3 100644 --- a/compiler/src/parsing/parser.dyp +++ b/compiler/src/parsing/parser.dyp @@ -22,7 +22,7 @@ include Parser_header %token LBRACK RBRACK LPAREN LPARENNOSPACE RPAREN LBRACE RBRACE LCARET RCARET %token CARET %token COMMA SEMI AS -%token THICKARROW ARROW PIPE +%token THICKARROW ARROW %token IS ISNT EQEQ LESSEQ GREATEREQ %token EQUAL GETS %token UNDERSCORE @@ -35,6 +35,7 @@ include Parser_header %token LET MUT REC IF WHEN ELSE MATCH WHILE %token AMPAMP PIPEPIPE NOT +%token AMP PIPE %token ENUM RECORD IMPORT EXPORT FOREIGN WASM PRIMITIVE %token EXCEPT FROM @@ -127,11 +128,17 @@ binop_expr : | binop_expr(<=p80) isnt_op eols? binop_expr(" } +rrcaret_op : + | RCARET RCARET { ">>" } +rrrcaret_op : + | RCARET RCARET RCARET { ">>>" } lesseq_op : | LESSEQ { "<=" } greatereq_op : | GREATEREQ { ">=" } +amp_op : + | AMP { "&" } ampamp_op : | AMPAMP { "&&" } +pipe_op : + | PIPE { "|" } pipepipe_op : | PIPEPIPE { "||" } pluseq_op : @@ -312,11 +331,17 @@ infix_op : | eqeq_op | plusplus_op | noteq_op + | caret_op | lcaret_op + | llcaret_op | rcaret_op + | rrcaret_op + | rrrcaret_op | lesseq_op | greatereq_op + | amp_op | ampamp_op + | pipe_op | pipepipe_op | pluseq_op | dasheq_op diff --git a/compiler/test/test_end_to_end.re b/compiler/test/test_end_to_end.re index 51d1a3b537..b92c44c140 100644 --- a/compiler/test/test_end_to_end.re +++ b/compiler/test/test_end_to_end.re @@ -190,6 +190,24 @@ let basic_functionality_tests = [ t("or2", "true || false", "true"), t("or3", "false || true", "true"), t("or4", "false || false", "false"), + t("land1", "1 & 1", "1"), + t("land2", "1 & 0", "0"), + t("land3", "0 & 1", "0"), + t("land4", "0 & 0", "0"), + t("lor1", "1 | 1", "1"), + t("lor2", "1 | 0", "1"), + t("lor3", "0 | 1", "1"), + t("lor4", "0 | 0", "0"), + t("lxor1", "1 ^ 1", "0"), + t("lxor2", "1 ^ 0", "1"), + t("lxor3", "0 ^ 1", "1"), + t("lxor4", "0 ^ 0", "0"), + t("lsl1", "7 << 1", "14"), + t("lsl2", "0 << 1", "0"), + t("lsr1", "7 >>> 1", "3"), + t("lsr2", "0 >>> 1", "0"), + t("asr1", "179 >> 1", "89"), + t("asr2", "0 >> 1", "0"), t("comp1", "if (2 < 3) {true} else {false}", "true"), te("comp1e", "if (2 < 3) {true} else {3}", "type"), t("comp2", "if (2 <= 3) {true} else {false}", "true"), diff --git a/docs/contributor/operator_precedence.md b/docs/contributor/operator_precedence.md index 8484053b09..69f5e83016 100644 --- a/docs/contributor/operator_precedence.md +++ b/docs/contributor/operator_precedence.md @@ -12,12 +12,12 @@ This table shows which operators take precedence over other operators, and can b | 130 | Exponentiation | right-to-left | NYI | | 120 | Multiplication
Division
Modulus | left-to-right | `… * …`
`… / …`
`… % …` | | 110 | Addition
Subtraction
String Concatenation | left-to-right | `… + …`
`… - …`
`… ++ …` | -| 100 | Bitwise Shift Left
Bitwise Shift Right
Bitwise Arithmetic Shift Right | left-to-right | NYI | +| 100 | Bitwise Shift Left
Bitwise Shift Right
Bitwise Arithmetic Shift Right | left-to-right | `… << …`
`… >> …`
`… >>> …` | | 90 | Less Than
Less Than or Equal To
Greater Than
Greater Than or Equal To | left-to-right | `… < …`
`… <= …`
`… > …`
`… >= …` | | 80 | Structural Equality
Structural Inequality
Physical Equality
Physical Inequality | left-to-right | `… == …`
`… != …`
`… is …`
`… isnt …`(NYI) | -| 70 | Bitwise AND | left-to-right | NYI | -| 60 | Bitwise XOR | left-to-right | NYI | -| 50 | Bitwise OR | left-to-right | NYI | +| 70 | Bitwise AND | left-to-right | `… & …` | +| 60 | Bitwise XOR | left-to-right | `… ^ …` | +| 50 | Bitwise OR | left-to-right | `… | …` | | 40 | Logical AND | left-to-right | `… && …` | | 30 | Logical OR | left-to-right | `… \|\| …` | | 20 | Ternary Conditional | right-to-left | NYI | diff --git a/stdlib/pervasives.gr b/stdlib/pervasives.gr index c265cfb0d9..baeac8dd6d 100644 --- a/stdlib/pervasives.gr +++ b/stdlib/pervasives.gr @@ -18,13 +18,13 @@ import foreign wasm numberGreaterEqual : (Number, Number) -> Bool as (>=) from ' // Number bit/logical operations import foreign wasm numberLnot : Number -> Number as lnot from 'stdlib-external/runtime' -import foreign wasm numberLand : (Number, Number) -> Number as land from 'stdlib-external/runtime' -import foreign wasm numberLor : (Number, Number) -> Number as lor from 'stdlib-external/runtime' -import foreign wasm numberLxor : (Number, Number) -> Number as lxor from 'stdlib-external/runtime' +import foreign wasm numberLand : (Number, Number) -> Number as (&) from 'stdlib-external/runtime' +import foreign wasm numberLor : (Number, Number) -> Number as (|) from 'stdlib-external/runtime' +import foreign wasm numberLxor : (Number, Number) -> Number as (^) from 'stdlib-external/runtime' -import foreign wasm numberLsl : (Number, Number) -> Number as lsl from 'stdlib-external/runtime' -import foreign wasm numberLsr : (Number, Number) -> Number as lsr from 'stdlib-external/runtime' -import foreign wasm numberAsr : (Number, Number) -> Number as asr from 'stdlib-external/runtime' +import foreign wasm numberLsl : (Number, Number) -> Number as (<<) from 'stdlib-external/runtime' +import foreign wasm numberLsr : (Number, Number) -> Number as (>>>) from 'stdlib-external/runtime' +import foreign wasm numberAsr : (Number, Number) -> Number as (>>) from 'stdlib-external/runtime' // Number coercions & conversions