Coder Social home page Coder Social logo

syntax's Introduction

⛔️ DEPRECATED ReScript Syntax

The ReScript syntax sources are now a part of the compiler repo (see https://github.com/rescript-lang/rescript-compiler/tree/master/res_syntax).

Please create any new issues or PRs directly in the compiler repo.

Contribute

Why

A detailed discussion by Jonathan Blow and Casey Muratori on why you would hand-roll a parser for a production quality programming language Discussion: Making Programming Language Parsers, etc

"One reason why I switched off these parser tools is that the promises didn't really materialize. The amount of work that I had to do change a yacc script from one language to a variant of that language was more than if I hand wrote the code myself. " J. Blow.

Setup & Usage (For Repo Devs Only)

Required:

  • OCaml 4.10 or later
  • Dune
  • Reanalyze
  • OS: macOS, Linux or Windows
git clone https://github.com/rescript-lang/syntax.git
cd syntax
opam install . --deps-only --with-test
make # or "dune build"

This will produce the three binaries rescript, tests and bench (with .exe extension on Windows).

We only build production binaries, even in dev mode. No need for a separate dev binary when the build is fast enough. Plus, this encourages proper benchmarking of the (production) binary each diff.

After you make a change:

make

Run the core tests:

make test

Run the extended tests (not fully working on Windows yet):

make roundtrip-test

Those will tell you whether you've got a test output difference. If it's intentional, check them in.

Debug a file:

# write code in test.res
dune exec -- rescript test.res # test printer
dune exec -- rescript -print ast test.res # print ast
dune exec -- rescript -print comments test.res # print comment table
dune exec -- rescript -print ml test.res # show ocaml code
dune exec -- rescript -print res -width 80 test.res # test printer and change default print width

Benchmark:

make bench

Enable stack trace:

# Before you run the binary
export OCAMLRUNPARAM="b"

This is likely a known knowledge: add the above line into your shell rc file so that every shell startup you have OCaml stack trace enabled.

Development Docs

Folder Structure

  • src contains all the parser/printer source code. Don't change folder structure without notice; The rescript-compiler repo uses this repo as a submodule and assumes src.
  • benchmarks, cli and tests contain the source code for the executables used for testing/benchmarking. These are not used by the rescript-compiler repo.

Error Reporting Logic

Right now, ReScript's compiler's error reporting mechanism, for architectural reasons, is independent from this syntax repo's error reporting mechanism. However, we do want a unified look when they report the errors in the terminal. This is currently achieved by (carefully...) duplicating the error report logic from the compiler repo to here (or vice-versa; either way, just keep them in sync). The files to sync are the compiler repo's super_location.ml and super_code_frame.ml, into this repo's res_diagnostics_printing_utils.ml. A few notes:

  • Some lines are lightly changed to fit this repo's needs; they're documented in the latter file.
  • Please keep these files lightweight and as dependency-less as possible, for easier syncing.
  • The syntax logic currently doesn't have warnings, only errors, and potentially more than one.
  • In the future, ideally, the error reporting logic would also be unified with GenType and Reanalyze's. It'd be painful to copy paste around all this reporting logic.
  • The errors are reported by the parser here.
  • Our editor plugin parses the error report from the compiler and from the syntax here.

Example API usage

let filename = "foo.res"
let src = FS.readFile filename

let p =
  (* intended for ocaml compiler *)
  let mode = Res_parser.ParseForTypeChecker in
  (* if you want to target the printer use: let mode = Res_parser.Default in*)
  Res_parser.make ~mode src filename

let structure = Res_core.parseImplementation p
let signature = Res_core.parseSpecification p

let () = match p.diagnostics with
| [] -> () (* no problems *)
| diagnostics -> (* parser contains problems *)
  Res_diagnostics.printReport diagnostics src

syntax's People

Contributors

a-c-sreedhar-reddy avatar ah-yu avatar amiralies avatar bobzhang avatar butterunderflow avatar chenglou avatar cknitt avatar cristianoc avatar dependabot[bot] avatar fhammerschmidt avatar glennsl avatar hugihlynsson avatar iwankaramazow avatar jchavarri avatar jsonkim avatar minnozz avatar mununki avatar namenu avatar nkrkv avatar ryyppy avatar sehun0819 avatar shalokshalom avatar tomgasson avatar zth avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

syntax's Issues

[printer] Superfluous brackets with ++ operator

let greet = (~firstName, ~lastName) => "Hello, " ++ firstName ++ " " ++ lastName;

gets printed as

let greet = (~firstName, ~lastName) => "Hello, " ++ (firstName ++ (" " ++ lastName))

by BS 8.1.1. yarn bsc -fmt.

napkin_diagnostics: Give access to start / end pos

As far as I understand, a failing parse can yield multiple diagnosis records, each with their own start / end pos.
Napkin_diagnostics.t doesn't expose the record internals, so I have no idea how to access them.

I guess we could expose this information with some helper functions?
The reason why I need this is that I need the line, column start and column end for each error to display in the playground editor and report the location correctly

Decouple Napkin_driver.parsingEngine from IO

I started the integration in the BuckleScript playground JS bundle and would like to use the Napkin_driver.parse_implementation function without any IO, but with a concrete source code string.

Right now the Napkin_driver.setup defaults to reading from stdin or a file.

For now I copy pasted the original code and removed the IO... maybe it's still desirable to change that for future tools?

JSX Children without delimiters

<Header> "Configuration"->React.string </Header>

This used to be possible, now the children require either {} or ().
I'm cool if that's by design, just wondering.

Can use a dot instead of a comma

I just came across this while writing some bindings:

module ModalContent = {
  @react.component @bs.module("semantic-ui-react")
  external make: (
    ~style: ReactDOMRe.Style.t=?.
    ~image: bool=?,
  ) => React.element = "ModalContent";
}

Look at the end of the style argument. The compiler accepts the . instead of the , seemingly just fine. You can also write it in one line without spaces, still doesn't complain.

Compile error when using Js.Promise.catch

Is this a bug or did I miss something else that changed with the new syntax?

Code:

let handler = (_event, _context) => {
  Js.Promise.make((~resolve, ~reject as _) => {
    resolve(. {
      statusCode: 200,
      body: "your data goes here"->Js.Nullable.return,
    })
  })
  |> Js.Promise.catch(error => {
       resolve({statusCode: 500, body: "error"->Js.Nullable.return})
     });
};

Error:

9 │      })
10 │    })
11 │    |> Js.Promise.catch(error => {
12 │         resolve({statusCode: 500, body: "error"->Js.Nullable.return})
13 │       });

Did you forget to write an expression here?

Document implicit `nonrec` in type definitions

type mylist<'a> =
   | Nil
   | Cons('a, mylist<'a>)

Gives

  1type mylist<'a> =
  2 │   | Nil
  3 │   | Cons('a, mylist<'a>);
  
  This type constructor's parameter, `mylist`, can't be found. Is it a typo?

I had to read the code to work out it's now implicitly nonrec

type rec mylist<'a> =
  | Nil
  | Cons('a, mylist<'a>);

I like that this change aligns types with with let-bindings. The error message could be more helpful

Error reporting format (and bsc/bsb integration)

This is probably highest priority. We need to fix this. cc @IwanKaramazow @bobzhang

  1. This is the reporting from the syntax itself:

Screen Shot 2020-07-25 at 4 18 15 PM

  1. This is from bsc -fmt (no super errors):

Screen Shot 2020-07-25 at 4 19 14 PM

  1. And this is from bsb + super errors (the non-super-errors version looks the same as the previous screenshot):

Screen Shot 2020-07-25 at 4 29 36 PM

Issues with 1:
We should probably drop the display now since this'll mainly be used in bsc, aka should go through the normal or super errors reporting pipeline (aka should not make its own inconsistent error display). Regarding the error location formatting, I saw https://github.com/BuckleScript/syntax/blob/a612f224a0f08e55b7f016cf7c9c4ae533f7e2a4/src/napkin_diagnostics.ml#L164
But that isn't needed if RLS turns on the env var BS_VSCODE=1: https://github.com/BuckleScript/bucklescript/blob/81b141146f520c804fb6a4fbb6f8df2d38522860/jscomp/super_errors/super_main.ml#L3
(Honestly I don't like that env var. And with the upcoming language-server changes, it also won't be needed. Also that env var disables super errors' much friendlier error explanations. Kinda like throwing the baby out with the bathwater here.)

Issues with 2:
New syntax files have super-errors turned on. bsc -fmt doesn't. This is inconsistent. Notice also the double location report. First location is reason-react/_none_??

Issues with 3:
Reporting has no indentation and double location like in previous issue (this isn't related to super-errors). If we solve the previous 2 issues, these ones will naturally go away.

Make array access syntax overload easier

in ocaml, to overload array access, people has to do

module Array = struct 
   let get = ..
end

a.(i) (* now it has different meanings *) 

ideally to make it lightweight as below

let (.[]) = your_get
a.(i) (* now has a special meaning *)

it has lots of use cases in data structres, list/slice/typed array

polymorphic suggestion for unhandled cases in switch uses backtick

let withpayload = #polymorphic(3)
switch withpayload {
  | #polymoprhic(c) => Js.log(c)
}
 13 │ 
  14 │ let withpayload = #polymorphic(3)
  15 │ switch withpayload {
  16 │   | #polymoprhic(c) => Js.log(c)
  17 │ }
  18 │ 
  19 │ let array = [1,2,3]
  
  You forgot to handle a possible case here, for example: 
`polymorphic _

remove the physical equality operator `===`

Unlike JavaScript's ===, for ocaml, most places where === is used, it is a wrong use case, it is useful in a small places where some internal optimizations is applied. In such small use cases, we can just call it like a normal function instead of using a special operator

Code refactoring

  • needs more comments
  • comment interleaving needs to be explained
  • it's unclear the division between multi_printer and driver. And the api for printer (multi_printer.print) vs parser (napkin_driver.print_implementation, print_interface) are inconsistent.

Syntax Bug: Closing parenthesis after inline module

I came across a nasty bug just now. I'm not sure if it's just this specific setup though. Some code of mine compiled fine but didn't work the way I expected. When I checked the JS Code, I found it was missing everything after a certain point (Still, it compiled fine).

I eventually found one closing parenthesis too much after a module definition.
See the following example:

open Ws

let wss = Server.make({port: 82})
let address = wss->Server.address
let log = msg => Js.log(`> Server: ${msg}`)
log(`Running on: ${address.address}:${address.port->string_of_int} (${address.family})`)

module ClientSet = {
  module T = Belt.Id.MakeComparable({
    type t = Client.t;
    let cmp = (a, b) => {
      compare(a->Client.getUniqueId, b->Client.getUniqueId);
    };
  });

  let empty = Belt.Set.make(~id=module (T));


}); // this ")" here, this can even be "))))))))))))))))" and it still compiles without complaint

Js.log("test"); // Is omitted from the compiled JS

Addition: When I run the file through napkinscript.exe -parse ns -print ns, everything after the module closing } gets deleted from it

Converting bs.raw

I'm trying to convert a bs.raw binding to the new syntax but can't get it working correctly. This might be related to #3 which also uses the {|val|} syntax, so might be something there?

let environment = %bs.raw({|process.env.NODE_ENV|})
3 │    | Production
4 │
5 │  let environment = %bs.raw({|process.env.NODE_ENV|})
                                                       ^
6 │
7 │  let make = () =>

Did you forget a `.` here?

JS Object access

This was fine:

e->ReactEvent.Form.target##value

Now this:

e->ReactEvent.Form.target["value"]

throws this error: This call is missing an argument of type ReactEvent.Form.t
And I need to fix it like this:

ReactEvent.Form.target(e)["value"]

Deatructive Substitution of Submodules

I discovered that destructive substitution of submodules is currently not possible in reason or rescript syntax, while it is in ocaml syntax.

In a large lib of ours, we use functors and destructive substitution.
Will this be suppprted in futute rescript versions?
Is there something I can do to bring submodule substitution to rescript? Or is this not desired?

I created an example sketch: https://sketch.sh/s/VBdVBVOFg1Vts7CFsLLIiy/

Relevant chapter in the ocaml manual: https://caml.inria.fr/pub/docs/manual-ocaml-4.06/extn.html#sec248

Octachron provided a working sketch in ml: https://sketch.sh/s/bIg7eLMxNZ58jwN9JmI3vz/

Allow non-symbol logical OCaml infix operators

Can the following operators be allowed in infix position? From https://caml.inria.fr/pub/docs/manual-ocaml/libref/Ocaml_operators.html :

lsl lsr asr
mod land lor xor
or (bonus, would be appreciated, but I understand if not)

My reasoning is that OCaml provides (most of) these specifically for bitwise operations, so it would be great to keep the ergonomics of bitwise operations which are after all not uncommon in JS (e.g. https://nodejs.org/dist/latest-v10.x/docs/api/fs.html#fs_fs_copyfile_src_dest_flags_callback ).

SwiftUI like trailing closures/expressions

JSX is amazing for building UIs. Especially when they are deeply nested. SwiftUI is using some more familiar language elements to make nested declarative UIs even more readable with trailing closures. It might be interesting to consider a syntax like this for Bucklescript as most people use it for building UIs.

NavigationView {
    List {
        Text("Hello World")
        Text("Hello World")
        Text("Hello World")
    }
}
@react.component
let make = () => {
   NavigationView {
     List(~color=`red) {
        [|
          Text("Hello World"),
          Text("Hello World"),
          Text("Hello World"),
        |]
     }
   }
}

Whereby the behavior of this is configurable just like JSX. In this case, the trailing expression could be passed as the ~children argument to the make function.

bsc.exe: unknown option '-c' error in `.re` files with bs-platform 8.1.1

I'm not clear if this is the repo where I should be filing this error (I'm happy to put it somewhere else), but I'm getting the following error at the top of every .re file in a project once I started using bs-platform 8.1.1:

<project_path>/node_modules/bs-platform/darwin/bsc.exe: unknown option '-c'.
Usage: bsc <options> <files>
Options are:
  -bs-super-errors  Better error message combined with other tools 
  -unboxed-types  unannotated unboxable types will be unboxed
  -bs-re-out  Print compiler output in Reason syntax
  -bs-jsx  Set jsx version
  -bs-refmt  Set customized refmt path
  -bs-gentype  Pass gentype command
  -bs-suffix  Set suffix to .bs.js
  -bs-no-implicit-include  Don't include current dir implicitly
  -bs-read-cmi  (internal) Assume mli always exist 
  -bs-D  Define conditional variable e.g, -D DEBUG=true
  -bs-unsafe-empty-array  Allow [||] to be polymorphic
  -nostdlib  Don't use stdlib
  -bs-internal-check  Built in check corrupted data
  -bs-list-conditionals  List existing conditional variables
  -bs-binary-ast  Generate binary .mli_ast and ml_ast
  -bs-simple-binary-ast  Generate binary .mliast_simple and mlast_simple
  -bs-syntax-only  only check syntax
  -bs-eval  (experimental) Set the string to be evaluated in OCaml syntax
  -e  (experimental) Set the string to be evaluated in ReasonML syntax
  -bs-cmi-only  Stop after generating cmi file
  -bs-cmi  Not using cached cmi, always generate cmi
  -bs-cmj  Not using cached cmj, always generate cmj
  -as-ppx  As ppx for editor integration
  -bs-g  debug mode
  -bs-sort-imports  Sort the imports by lexical order so the output will be more stable (default false)
  -bs-no-sort-imports  No sort (see -bs-sort-imports)
  -bs-package-name  set package name, useful when you want to produce npm packages
  -bs-ns  set package map, not only set package name but also use it as a namespace
  -bs-no-version-header  Don't print version header
  -bs-package-output  set npm-output-path: [opt_module]:path, for example: 'lib/cjs', 'amdjs:lib/amdjs', 'es6:lib/es6' 
  -bs-no-builtin-ppx disable built-in ppx (internal use)
  -bs-cross-module-opt enable cross module inlining(experimental), default(false)
  -bs-no-cross-module-opt disable cross module inlining(experimental)
  -bs-diagnose  More verbose output
  -bs-no-check-div-by-zero  unsafe mode, don't check div by zero and mod by zero
  -bs-noassertfalse  no code for assert false
  -noassert  Do not compile assertion checks
  -bs-loc  dont display location with -dtypedtree, -dparsetree
  -impl <file>  Compile <file> as a .ml file
  -intf <file>  Compile <file> as a .mli file
  -dtypedtree  debug typedtree
  -dparsetree  debug parsetree
  -drawlambda  debug raw lambda
  -dsource  print source
  -fmt  (internal) format as Res syntax
  -where  Print location of standard library and exit
  -ppx <command>  Pipe abstract syntax trees through preprocessor <command>
  -open <module>  Opens the module <module> before typing
  -verbose  Print calls to external commands
  -keep-locs  Keep locations in .cmi files
  -no-keep-locs  Do not keep locations in .cmi files
  -nopervasives  (undocumented)
  -v  Print compiler version and location of standard library and exit
  -version  Print version and exit
  -I <dir>  Add <dir> to the list of include directories
  -pp <command>  Pipe sources through preprocessor <command>
  -absname  Show absolute filenames in error messages
  -bs-no-bin-annot  disable binary annotations (by default on)
  -i  Print inferred interface
  -nolabels  Ignore non-optional labels in types
  -no-alias-deps  Do not record dependencies for module aliases
  -o <file>  Set output file name to <file>
  -principal  Check principality of type inference
  -short-paths  Shorten paths in types
  -unsafe  Do not compile bounds checking on array and string access
  -w <list>  Enable or disable warnings according to <list>:
        +<spec>   enable warnings in <spec>
        -<spec>   disable warnings in <spec>
        @<spec>   enable warnings in <spec> and treat them as errors
     <spec> can be:
        <num>             a single warning number
        <num1>..<num2>    a range of consecutive warning numbers
        <letter>          a predefined set
     default setting is +a-4-9-20-40-41-42-50-61-102
  -warn-error <list>  Enable or disable error status for warnings according
     to <list>.  See option -w for the syntax of <list>.
     Default setting is -a+5+6+101
  -warn-help  Show description of warning numbers
  -color {auto|always|never}  Enable or disable colors in compiler messages
    The following settings are supported:
      auto    use heuristics to enable colors only if supported
      always  enable colors
      never   disable colors
    The default setting is 'auto', and the current heuristic
    checks that the TERM environment variable exists and is
    not empty or "dumb", and that isatty(stderr) holds.
  -help  Display this list of options
  --help  Display this list of options```

Matching polymorphic variant tags

The syntax for matching a polymorphic variant type uses a double hashtag

type nums = [ | #one | #two | #three];

type alphas = [ | #a | #b | #c];

type alphanums = [ nums | alphas ];

let a: alphanums = #a;

switch a {
| ##alphas => Js.log("alphas")
| ##nums => Js.log("nums")
};

What if we used the spread operator? Either before or after the hashtag

switch a {
| #...alphas => Js.log("alphas")
| #...nums => Js.log("nums")
};

Unicode support in strings

Js.log("Sehr schön")
Js.log(`Sehr schön`)
Js.log(j`Sehr schön`)

gives me

Sehr schön
Sehr schön
Sehr schön

It would be great if Unicode worked for all three, not just for the last one.

Clarification regarding infix operators usage

As far as I know, infix operators are banned from the new syntax, but it seems operators declared in OCaml/old ReasonML can be used in the new syntax (I tried recently with some common operators like <$> <|> >=>, all worked as expected).

Since we have a middle sized application with ~1000 modules, and we use cutom operators quiete extensively, I wanted to get some clarification regarding the usage of custom operators. Will this be banned eventually?

(Also, and for what it's worth, i really do hope custom operators will be fully supported again one day 😄 ).

Edit: After testing again with BS 8.2.0, it seems that the custom operators, even those written in OCaml/ReasonML don't work at all in the new syntax 😞

Impossible to use "curried" operators

In OCaml (and old ReasonML), this works:

let addOne = (+) 1 in

Js.log (addOne 41) (* Displays 42 *)

But it turns out the above doesn't work with the new syntax.
That being said, the following does compile:

let addOne = \"+"(1)

Js.log(addOne(41)) // Displays 42 as well

IMHO \"+"(1) is not easier to read, or clearer than (+) 😕
Especially since theses operators will most of the time be read as strings which they are not.

Is it by design, or is it in progress?

Add line directive syntax support

In OCaml, you can tell the compiler to set the linenumber / filename for any code like this:

# 20 "playground.ml"
let _ = 1 + 1

In the new BuckleScript syntax, this construct (# [linenum] "filename") doesn't exist.

Use case
In reasonml.org, we test compile our code snippets. Since we are using the line preview mode for errors, we'd like to inject the corrected line number and the filename via the directive before we compile each snippet. Would be great to have that feature available for .res snippets as well.

Syntax
I know that # is already reserved for poly-variants.. since this feature is not necessarily interesting for end users, i guess having less ergonomic syntax alternatives is okay as well

FCM syntax simplification

Current:

let fn = (~x: module (X)) => {
  let module (X) = x
  X.x
};

Prolly can be simplified:

let fn = (~x : module X) => {
   let module X = x
   X.x
}

Missing license

Just a little nitpick, the package.json specifies the license is MIT, but the project doesn't have any license files.

[printer] Record fields punning

type a = int
type b = string

type r = { a, b }

is printed (by BS 8.1.1 bsc -fmt) to

type a = int
type b = string

type r = {a: a, b: b}

IMHO the output should use punning for the record fields (like in the input).

Allow indentation in multiline strings

It was discussed before but I am afraid that adding this later might introduce a breaking change. So making an issue here so the choice can be made to implement it early or there is a solution that is non-breaking.

Context: if multiline strings cannot be indented, multiline strings are not very friendly to use at all, as generally code is indented.

Proposal:

  let str = `
  this is a multiline string
  `
//^ the last backtick is determining the indent the string follows 
// this string will actually be "this is a multiline string"

This means that in a multiline string there should always be a newline after the first backtick, with the last backtick indicating the indentation. Also pretty-printing can now shift strings in the right indentation.

Prior art is Elixir, Swift and Python, all adopting this style of multiline strings. Best docs here.

The only difference is that in some languages by default a newline is added on the last line. So that

  let str = `
  this is a multiline string
  `

Will actually be this is a multiline string\n (Elixir). I actually think this is not great because we can always explicitly add a newline if we want.

Of course

let str = `this is a single line string`

is still valid if the backticks are both on the same line.

[parser] [internals] tweak breadcrumb api.

leaveBreadcrumb is a function that augments the parser state with "breadcrumbs". Whenever an error occurs, the breadcrumbs give us an idea of what we're actually trying to parse.

Imagine having the following code:

for _ in 0 to 10 {

}

There's an expression missing between { and }. The parser will basically leave a breadcrumb "I'm-trying-to-parse-an-expression" and see the token }. From here we can deduce that we're missing an expression and give an error like:
image

There's one problem however, every leaveBreadcrumb needs to be followed by eatBreadcrumb.
It's easy to forget writing an eatBreadcrumb, resulting in the wrong "trail of breadcrumbs" in the parser.
Can we change the api, so we know when it goes out of sync?

Idea:

make eatBreadcrumb also take a grammar, so it's easier to check that the calls are matching

avoid linking unix module

In recent commits of napkin, it seems Unix module is linked in.
Follow the same convention of native compiler, we should avoid linking in Unix/Dynlink module which is not very platform agnostics.

Seems to be introduced by 90ba873
cc @IwanKaramazow

Potentially better list syntax: `list{1, 2, 3}`

Benefit of list{1, 2, 3} over the current list[1, 2, 3]:

  • More familiar in many other languages.
  • Doesn't turn list into a keyword anymore. You'll get to use let list = foo again.

Latter is important if we ever expand to set{1, 2}, map{1: 2}, stream{1, 2}, etc.

Converting regex statement

This regex statement gives me all kinds of errors

let titleRegex = %re({|/((^[a-zåäö\-\:\s]+\d{1,}[:-]?\w?)|^[a-zåäö]+)|(([a-zåäö\-\/]\s?)+,\s([a-zåäö\-]\s?)+)|([a-zåäö/]+ till salu)/ig|})

It seems like it's giving me two errors for åäö, one empty error and one highlighting the actual character.

Screenshot 2020-07-02 08 23 46
Screenshot 2020-07-02 08 23 51
Screenshot 2020-07-02 08 23 57
Screenshot 2020-07-02 08 24 05
Screenshot 2020-07-02 08 24 11
Screenshot 2020-07-02 08 24 18
Screenshot 2020-07-02 08 24 23
Screenshot 2020-07-02 08 24 31

Uppercase generics not allowed

I'm wondering if that is intentional ( I haven't seen it in the change list):

module Test = {
  type x('A) = 'A;
  type y = x(string);
};

Old syntax is fine.

module Test = {
  type x<'A> = 'A;
  type y = x<string>;
};

New syntax says [E] Line 2, 18: Did you forget a > here?, where as type x<'a> = 'a; works fine

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.