Skip to content

Commit

Permalink
scanner work
Browse files Browse the repository at this point in the history
  • Loading branch information
bcpeinhardt committed Aug 27, 2024
1 parent a34ee07 commit c859d9d
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 81 deletions.
105 changes: 57 additions & 48 deletions priv/static/squared_away.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2561,7 +2561,7 @@ var StringLiteral = class extends CustomType {
};
var ScanError = class extends CustomType {
};
function maybe_parse_integer(loop$src, loop$acc) {
function parse_integer(loop$src, loop$acc) {
while (true) {
let src = loop$src;
let acc = loop$acc;
Expand Down Expand Up @@ -2616,17 +2616,14 @@ function maybe_parse_integer(loop$src, loop$acc) {
loop$src = rest;
loop$acc = acc + x;
} else {
let $ = parse2(acc);
if ($.isOk()) {
let x = $[0];
return new Some([x, src]);
} else {
return new None();
}
let _pipe = parse2(acc);
return map2(_pipe, (n) => {
return [n, src];
});
}
}
}
function maybe_parse_cell_ref(loop$src, loop$acc) {
function parse_cell_ref(loop$src, loop$acc) {
while (true) {
let src = loop$src;
let acc = loop$acc;
Expand Down Expand Up @@ -2762,16 +2759,16 @@ function maybe_parse_cell_ref(loop$src, loop$acc) {
loop$acc = acc + l;
} else {
if (acc === "") {
return new None();
return new Error(void 0);
} else {
let $ = maybe_parse_integer(src, "");
if ($ instanceof Some) {
let n = $[0][0];
let rest = $[0][1];
return new Some([acc + to_string2(n), rest]);
} else {
return new None();
}
return try$(
parse_integer(src, ""),
(_use0) => {
let n = _use0[0];
let rest = _use0[1];
return new Ok([acc + to_string2(n), rest]);
}
);
}
}
}
Expand Down Expand Up @@ -2864,47 +2861,59 @@ function do_scan(loop$src, loop$acc) {
loop$src = trim_left2(rest);
loop$acc = prepend(new RParen(), acc);
} else {
let $ = maybe_parse_integer(src, "");
if ($ instanceof Some) {
let $ = parse_integer(src, "");
if ($.isOk()) {
let n = $[0][0];
let rest = $[0][1];
if (rest.startsWith(".")) {
let rest$1 = rest.slice(1);
let $1 = maybe_parse_integer(rest$1, "");
if ($1 instanceof Some) {
let m = $1[0][0];
let rest$2 = $1[0][1];
let $2 = parse(to_string2(n) + "." + to_string2(m));
if (!$2.isOk()) {
throw makeError(
"assignment_no_match",
"squared_away/lang/scanner",
98,
"do_scan",
"Assignment pattern did not match",
{ value: $2 }
return try$(
(() => {
let _pipe = parse_integer(rest$1, "");
return replace_error(_pipe, new ScanError());
})(),
(_use0) => {
let m = _use0[0];
let rest$2 = _use0[1];
let $1 = parse(
to_string2(n) + "." + to_string2(m)
);
if (!$1.isOk()) {
throw makeError(
"assignment_no_match",
"squared_away/lang/scanner",
99,
"",
"Assignment pattern did not match",
{ value: $1 }
);
}
let f = $1[0];
return do_scan(
trim_left2(rest$2),
prepend(new FloatLiteral(f), acc)
);
}
let f = $2[0];
loop$src = trim_left2(rest$2);
loop$acc = prepend(new FloatLiteral(f), acc);
} else {
return new Error(new ScanError());
}
);
} else {
loop$src = trim_left2(rest);
loop$acc = prepend(new IntegerLiteral(n), acc);
}
} else {
let $1 = maybe_parse_cell_ref(src, "");
if ($1 instanceof Some) {
let cell_ref = $1[0][0];
let rest = $1[0][1];
loop$src = trim_left2(rest);
loop$acc = prepend(new CellReference(cell_ref), acc);
} else {
return new Error(new ScanError());
}
return try$(
(() => {
let _pipe = parse_cell_ref(src, "");
return replace_error(_pipe, new ScanError());
})(),
(_use0) => {
let cell_ref = _use0[0];
let rest = _use0[1];
return do_scan(
trim_left2(rest),
prepend(new CellReference(cell_ref), acc)
);
}
);
}
}
}
Expand Down
55 changes: 23 additions & 32 deletions src/squared_away/lang/scanner.gleam
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import gleam/float
import gleam/int
import gleam/list
import gleam/option.{type Option, None, Some}
import gleam/result
import gleam/string

pub type Token {
Expand Down Expand Up @@ -88,36 +88,34 @@ fn do_scan(src: String, acc: List(Token)) -> Result(List(Token), ScanError) {
"(" <> rest -> do_scan(string.trim_left(rest), [LParen, ..acc])
")" <> rest -> do_scan(string.trim_left(rest), [RParen, ..acc])
_ -> {
case maybe_parse_integer(src, "") {
Some(#(n, rest)) -> {
case parse_integer(src, "") {
Ok(#(n, rest)) -> {
// Might be a float
case rest {
"." <> rest -> {
case maybe_parse_integer(rest, "") {
Some(#(m, rest)) -> {
let assert Ok(f) =
float.parse(int.to_string(n) <> "." <> int.to_string(m))
do_scan(string.trim_left(rest), [FloatLiteral(f), ..acc])
}
None -> Error(ScanError)
}
use #(m, rest) <- result.try(
parse_integer(rest, "") |> result.replace_error(ScanError),
)
let assert Ok(f) =
float.parse(int.to_string(n) <> "." <> int.to_string(m))
do_scan(string.trim_left(rest), [FloatLiteral(f), ..acc])
}
_ -> do_scan(string.trim_left(rest), [IntegerLiteral(n), ..acc])
}
}

None ->
case maybe_parse_cell_ref(src, "") {
Some(#(cell_ref, rest)) ->
do_scan(string.trim_left(rest), [CellReference(cell_ref), ..acc])
None -> Error(ScanError)
}
Error(_) -> {
use #(cell_ref, rest) <- result.try(
parse_cell_ref(src, "") |> result.replace_error(ScanError),
)
do_scan(string.trim_left(rest), [CellReference(cell_ref), ..acc])
}
}
}
}
}

fn maybe_parse_cell_ref(src: String, acc: String) -> Option(#(String, String)) {
fn parse_cell_ref(src: String, acc: String) -> Result(#(String, String), Nil) {
// A cell reference is a string of characters followed by a string of numbers (aka an int),
// so we can reuse the integer parsing at a slight runtime cost for now
case src {
Expand Down Expand Up @@ -146,23 +144,21 @@ fn maybe_parse_cell_ref(src: String, acc: String) -> Option(#(String, String)) {
| "W" as l <> rest
| "X" as l <> rest
| "Y" as l <> rest
| "Z" as l <> rest -> maybe_parse_cell_ref(rest, acc <> l)
| "Z" as l <> rest -> parse_cell_ref(rest, acc <> l)
_ -> {
case acc {
// Meaning we called this on something that didnt start with a capital letter
"" -> None
"" -> Error(Nil)
_ -> {
case maybe_parse_integer(src, "") {
Some(#(n, rest)) -> Some(#(acc <> int.to_string(n), rest))
None -> None
}
use #(n, rest) <- result.try(parse_integer(src, ""))
Ok(#(acc <> int.to_string(n), rest))
}
}
}
}
}

fn maybe_parse_integer(src: String, acc: String) -> Option(#(Int, String)) {
fn parse_integer(src: String, acc: String) -> Result(#(Int, String), Nil) {
case src {
"1" as x <> rest
| "2" as x <> rest
Expand All @@ -173,12 +169,7 @@ fn maybe_parse_integer(src: String, acc: String) -> Option(#(Int, String)) {
| "7" as x <> rest
| "8" as x <> rest
| "9" as x <> rest
| "0" as x <> rest -> maybe_parse_integer(rest, acc <> x)
_ -> {
case int.parse(acc) {
Ok(x) -> Some(#(x, src))
_ -> None
}
}
| "0" as x <> rest -> parse_integer(rest, acc <> x)
_ -> int.parse(acc) |> result.map(fn(n) { #(n, src) })
}
}
1 change: 0 additions & 1 deletion test/squared_away_test.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import gleam/dict
import gleam/list
import gleeunit
import gleeunit/should
import squared_away/lang
import squared_away/lang/interpreter
import squared_away/lang/parser
import squared_away/lang/scanner
Expand Down

0 comments on commit c859d9d

Please sign in to comment.