store location on RESyntaxError; export parse() function

This commit is contained in:
Vyacheslav Matyukhin 2022-06-22 00:34:35 +03:00
parent 75dfb724ec
commit 84a0d83efb
No known key found for this signature in database
GPG Key ID: 3D2A774C5489F96C
5 changed files with 33 additions and 5 deletions

View File

@ -10,6 +10,7 @@ import {
evaluatePartialUsingExternalBindings, evaluatePartialUsingExternalBindings,
evaluateUsingOptions, evaluateUsingOptions,
foreignFunctionInterface, foreignFunctionInterface,
parse as parseRescript,
} from "../rescript/TypescriptInterface.gen"; } from "../rescript/TypescriptInterface.gen";
export { export {
makeSampleSetDist, makeSampleSetDist,
@ -31,7 +32,7 @@ import {
convertRawToTypescript, convertRawToTypescript,
lambdaValue, lambdaValue,
} from "./rescript_interop"; } from "./rescript_interop";
import { result, resultMap, tag, tagged } from "./types"; import { Ok, result, resultMap, tag, tagged } from "./types";
import { Distribution, shape } from "./distribution"; import { Distribution, shape } from "./distribution";
export { Distribution, resultMap, defaultEnvironment }; export { Distribution, resultMap, defaultEnvironment };
@ -58,6 +59,23 @@ export function run(
return resultMap(res, (x) => createTsExport(x, e)); return resultMap(res, (x) => createTsExport(x, e));
} }
export function parse(
squiggleString: string
): result<null, Extract<errorValue, { tag: "RESyntaxError" }>> {
const maybeExpression = parseRescript(squiggleString);
if (maybeExpression.tag === "Ok") {
return Ok(null); // TODO - return AST
} else {
if (
typeof maybeExpression.value !== "object" ||
maybeExpression.value.tag !== "RESyntaxError"
) {
throw new Error("Expected syntax error");
}
return { tag: "Error", value: maybeExpression.value };
}
}
// Run Partial. A partial is a block of code that doesn't return a value // Run Partial. A partial is a block of code that doesn't return a value
export function runPartial( export function runPartial(
squiggleString: string, squiggleString: string,

View File

@ -1,3 +1,6 @@
@gentype.import("peggy") @genType.as("LocationRange")
type location
@genType @genType
type errorValue = type errorValue =
| REArityError(option<string>, int, int) //TODO: Binding a lambda to a variable should record the variable name in lambda for error reporting | REArityError(option<string>, int, int) //TODO: Binding a lambda to a variable should record the variable name in lambda for error reporting
@ -14,7 +17,7 @@ type errorValue =
| REOperationError(Operation.operationError) | REOperationError(Operation.operationError)
| RERecordPropertyNotFound(string, string) | RERecordPropertyNotFound(string, string)
| RESymbolNotFound(string) | RESymbolNotFound(string)
| RESyntaxError(string) | RESyntaxError(string, option<location>)
| RETodo(string) // To do | RETodo(string) // To do
| REUnitNotFound(string) | REUnitNotFound(string)
@ -50,7 +53,7 @@ let errorToString = err =>
| RENotAFunction(valueString) => `${valueString} is not a function` | RENotAFunction(valueString) => `${valueString} is not a function`
| RERecordPropertyNotFound(msg, index) => `${msg}: ${index}` | RERecordPropertyNotFound(msg, index) => `${msg}: ${index}`
| RESymbolNotFound(symbolName) => `${symbolName} is not defined` | RESymbolNotFound(symbolName) => `${symbolName} is not defined`
| RESyntaxError(desc) => `Syntax Error: ${desc}` | RESyntaxError(desc, _) => `Syntax Error: ${desc}`
| RETodo(msg) => `TODO: ${msg}` | RETodo(msg) => `TODO: ${msg}`
| REExpectedType(typeName) => `Expected type: ${typeName}` | REExpectedType(typeName) => `Expected type: ${typeName}`
| REUnitNotFound(unitName) => `Unit not found: ${unitName}` | REUnitNotFound(unitName) => `Unit not found: ${unitName}`

View File

@ -157,7 +157,7 @@ let evaluatePartialUsingExternalBindings = (
switch rAnswer { switch rAnswer {
| Ok(EvRecord(externalBindings)) => Ok(externalBindings) | Ok(EvRecord(externalBindings)) => Ok(externalBindings)
| Ok(_) => | Ok(_) =>
Error(Reducer_ErrorValue.RESyntaxError(`Partials must end with an assignment or record`)) Error(Reducer_ErrorValue.RESyntaxError(`Partials must end with an assignment or record`, None))
| Error(err) => err->Error | Error(err) => err->Error
} }
} }

View File

@ -5,11 +5,15 @@ type node = {"type": string}
@module("./Reducer_Peggy_GeneratedParser.js") external parse__: string => node = "parse" @module("./Reducer_Peggy_GeneratedParser.js") external parse__: string => node = "parse"
let syntaxErrorToLocation: Js.Exn.t => Reducer_ErrorValue.location = error => %raw(`error.location`)
@genType
let parse = (expr: string): result<node, errorValue> => let parse = (expr: string): result<node, errorValue> =>
try { try {
Ok(parse__(expr)) Ok(parse__(expr))
} catch { } catch {
| Js.Exn.Error(obj) => REJavaScriptExn(Js.Exn.message(obj), Js.Exn.name(obj))->Error | Js.Exn.Error(obj) =>
RESyntaxError(Belt.Option.getExn(Js.Exn.message(obj)), syntaxErrorToLocation(obj)->Some)->Error
} }
type nodeBlock = {...node, "statements": array<node>} type nodeBlock = {...node, "statements": array<node>}

View File

@ -40,6 +40,9 @@ let evaluate = Reducer.evaluate
@genType @genType
let evaluateUsingOptions = Reducer.evaluateUsingOptions let evaluateUsingOptions = Reducer.evaluateUsingOptions
@genType
let parse = Reducer_Peggy_Parse.parse
@genType @genType
let evaluatePartialUsingExternalBindings = Reducer.evaluatePartialUsingExternalBindings let evaluatePartialUsingExternalBindings = Reducer.evaluatePartialUsingExternalBindings