Skip to content

Instantly share code, notes, and snippets.

@jchavarri
Created September 21, 2017 21:39
Show Gist options
  • Save jchavarri/06a1874e6940ee73a60b228aca682ee6 to your computer and use it in GitHub Desktop.
Save jchavarri/06a1874e6940ee73a60b228aca682ee6 to your computer and use it in GitHub Desktop.
Triggers a bad error parsing
type token =
| OpenParen
| CloseParen
| Number string
| String string;
type state =
| Init
| ParsingNumber
| ParsingString;
/* Not used for anything, but keeping for doc purposes */
type machine = {
current: option token,
parsedTokens: list token,
state
};
let initialMachine = {current: None, parsedTokens: [], state: Init};
external stringify : Js.t {..} => string = "" [@@bs.val] [@@bs.scope "JSON"];
let explode s => {
let rec exp i l =>
if (i < 0) {
l
} else {
exp (i - 1) [s.[i], ...l]
};
exp (String.length s - 1) []
};
let tokenizer input => {
/* A `current` variable for tracking our position in the code like a cursor. */
/* let current = ref 0; */
/* And a `tokens` array for pushing our tokens to. */
/* let tokens = []; */
/* We start by creating a `while` loop where we are setting up our `current`
variable to be incremented as much as we want `inside` the loop.
We do this because we may want to increment `current` many times within a
single loop because our tokens can be any length. */
/* We're also going to store the `current` character in the `input`. */
let rec tok input current tokens state =>
/* The first thing we want to check for is an open parenthesis. This will
later be used for `CallExpression` but for now we only care about the
character.
We check to see if we have an open parenthesis: */
switch (input, current, tokens, state) {
/* If we do, we push a new token with the type `paren` and set the value
to an open parenthesis. */
| (['(', ...xi], None, t, Init) => tok xi None [OpenParen, ...t] Init
| ([')', ...xi], None, t, Init) => tok xi None [CloseParen, ...t] Init
| ([' ' | '\t' | '\r' | '\n', ...xi], None, t, Init) => tok xi None t Init
| (['"', ...xi], None, t, Init) => tok xi (Some (String "")) t ParsingString
| (['"', ...xi], Some (String c), t, ParsingString) => tok xi None [String c, ...t] Init
| ([i, ...xi], Some (String c), t, ParsingString) =>
tok xi (Some (Number (c ^ Char.escaped i))) t ParsingString
| (['0'..'9' as i, ...xi], None, t, Init) => tok xi (Some (Number (Char.escaped i))) t ParsingNumber
| (['0'..'9' as i, ...xi], Some (Number c), t, ParsingNumber) =>
tok xi (Some (Number (c ^ Char.escaped i))) t ParsingNumber
| ([' ' as i, ...xi], Some (Number c), t, ParsingNumber) => tok xi None [Number c] Init
| ([], None, t, Init) => List.rev t
};
tok (explode input) initialMachine.current initialMachine.parsedTokens initialMachine.state
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment