locations for syntax errors

This commit is contained in:
Vyacheslav Matyukhin 2022-10-05 05:17:30 +04:00
parent 298492b3b8
commit 234ebe2103
No known key found for this signature in database
GPG Key ID: 3D2A774C5489F96C
12 changed files with 34 additions and 34 deletions

View File

@ -22,7 +22,7 @@ let expectExpressionToBe = (expr, answer, ~v="_", ()) => {
} else { } else {
let a2 = let a2 =
rExpr rExpr
->E.R2.errMap(e => e->SqError.Message.fromParseError->SqError.fromMessage) ->E.R2.errMap(e => e->SqError.fromParseError)
->Result.flatMap(expr => Expression.BackCompatible.evaluate(expr)) ->Result.flatMap(expr => Expression.BackCompatible.evaluate(expr))
->Reducer_Value.toStringResultOkless ->Reducer_Value.toStringResultOkless
(a1, a2)->expect->toEqual((answer, v)) (a1, a2)->expect->toEqual((answer, v))

View File

@ -25,7 +25,7 @@ x=1`,
let mainIncludes = Project.getIncludes(project, "main") let mainIncludes = Project.getIncludes(project, "main")
switch mainIncludes { switch mainIncludes {
| Ok(includes) => expect(includes) == ["common"] | Ok(includes) => expect(includes) == ["common"]
| Error(error) => fail(error->SqError.Message.toString) | Error(error) => fail(error->SqError.toString)
} }
}) })
test("past chain", () => { test("past chain", () => {
@ -60,7 +60,7 @@ x=1`,
let mainIncludes = Project.getIncludes(project, "main") let mainIncludes = Project.getIncludes(project, "main")
switch mainIncludes { switch mainIncludes {
| Ok(includes) => expect(includes) == ["common", "myModule"] | Ok(includes) => expect(includes) == ["common", "myModule"]
| Error(error) => fail(error->SqError.Message.toString) | Error(error) => fail(error->SqError.toString)
} }
}) })
@ -99,7 +99,7 @@ x=1`,
let mainIncludes = Project.getIncludes(project, "main") let mainIncludes = Project.getIncludes(project, "main")
switch mainIncludes { switch mainIncludes {
| Ok(includes) => expect(includes) == ["common", "common2", "myModule"] | Ok(includes) => expect(includes) == ["common", "common2", "myModule"]
| Error(error) => fail(error->SqError.Message.toString) | Error(error) => fail(error->SqError.toString)
} }
}) })
test("direct past chain", () => { test("direct past chain", () => {

View File

@ -36,7 +36,7 @@ Here we will finally proceed to a real life scenario. */
/* Parse includes has set the includes */ /* Parse includes has set the includes */
switch project->Project.getIncludes("main") { switch project->Project.getIncludes("main") {
| Ok(includes) => includes->expect == ["common"] | Ok(includes) => includes->expect == ["common"]
| Error(err) => err->SqError.Message.toString->fail | Error(err) => err->SqError.toString->fail
} }
/* If the includes cannot be parsed then you get a syntax error. /* If the includes cannot be parsed then you get a syntax error.
Otherwise you get the includes. Otherwise you get the includes.
@ -85,7 +85,7 @@ Here we will finally proceed to a real life scenario. */
let rIncludes = project->Project.getIncludes(sourceName) let rIncludes = project->Project.getIncludes(sourceName)
switch rIncludes { switch rIncludes {
/* Maybe there is an include syntax error */ /* Maybe there is an include syntax error */
| Error(err) => err->SqError.Message.toString->Js.Exn.raiseError | Error(err) => err->SqError.toString->Js.Exn.raiseError
| Ok(includes) => | Ok(includes) =>
includes->Belt.Array.forEach(newIncludeName => { includes->Belt.Array.forEach(newIncludeName => {
@ -169,7 +169,7 @@ Here we will finally proceed to a real life scenario. */
test("getIncludes", () => { test("getIncludes", () => {
switch Project.getIncludes(project, "main") { switch Project.getIncludes(project, "main") {
| Ok(includes) => includes->expect == ["common"] | Ok(includes) => includes->expect == ["common"]
| Error(err) => err->SqError.Message.toString->fail | Error(err) => err->SqError.toString->fail
} }
}) })
}) })

View File

@ -104,10 +104,8 @@ let cleanAllResults = (project: reducerProject): unit => project->Private.cleanA
To set the includes one first has to call "parseIncludes". The parsed includes or the parser error is returned. To set the includes one first has to call "parseIncludes". The parsed includes or the parser error is returned.
*/ */
@genType @genType
let getIncludes = (project: reducerProject, sourceId: string): result< let getIncludes = (project: reducerProject, sourceId: string): result<array<string>, error> =>
array<string>, project->Private.getIncludes(sourceId)
errorMessage,
> => project->Private.getIncludes(sourceId)
/* Other sources contributing to the global namespace of this source. */ /* Other sources contributing to the global namespace of this source. */
@genType @genType

View File

@ -12,5 +12,5 @@ let createContext = (stdLib: Reducer_Namespace.t, environment: Reducer_T.environ
} }
let currentFunctionName = (t: t): string => { let currentFunctionName = (t: t): string => {
t.inFunction->E.O2.fmap(Reducer_Lambda_T.name)->E.O2.default("<top>") t.inFunction->E.O2.fmap(Reducer_Lambda_T.name)->E.O2.default(Reducer_T.topFrameName)
} }

View File

@ -149,7 +149,5 @@ module BackCompatible = {
} }
let evaluateString = (peggyCode: string): result<T.value, SqError.t> => let evaluateString = (peggyCode: string): result<T.value, SqError.t> =>
parse(peggyCode) parse(peggyCode)->E.R2.errMap(e => e->SqError.fromParseError)->Result.flatMap(evaluate)
->E.R2.errMap(e => e->SqError.Message.fromParseError->SqError.fromMessage)
->Result.flatMap(evaluate)
} }

View File

@ -27,6 +27,9 @@ let extend = (t: t, name: string, location: option<Reducer_Peggy_Parse.location>
location: location, location: location,
}) })
let makeSingleFrameStack = (location: Reducer_Peggy_Parse.location): t =>
make()->extend(Reducer_T.topFrameName, Some(location))
let toString = (t: t) => let toString = (t: t) =>
t t
->Belt.List.map(s => " " ++ s->Frame.toString ++ "\n") ->Belt.List.map(s => " " ++ s->Frame.toString ++ "\n")

View File

@ -65,3 +65,5 @@ and context = {
} }
and reducerFn = (expression, context) => (value, context) and reducerFn = (expression, context) => (value, context)
let topFrameName = "<top>"

View File

@ -1,7 +1,7 @@
@module("./ReducerProject_IncludeParser.js") @module("./ReducerProject_IncludeParser.js")
external parse__: string => array<array<string>> = "parse" external parse__: string => array<array<string>> = "parse"
let parseIncludes = (expr: string): result<array<(string, string)>, SqError.Message.t> => let parseIncludes = (expr: string): result<array<(string, string)>, SqError.t> =>
try { try {
let answer = parse__(expr) let answer = parse__(expr)
// let logEntry = answer->Js.Array2.joinWith(",") // let logEntry = answer->Js.Array2.joinWith(",")
@ -9,8 +9,9 @@ let parseIncludes = (expr: string): result<array<(string, string)>, SqError.Mess
Belt.Array.map(answer, item => (item[0], item[1]))->Ok Belt.Array.map(answer, item => (item[0], item[1]))->Ok
} catch { } catch {
| Js.Exn.Error(obj) => | Js.Exn.Error(obj) =>
RESyntaxError( RESyntaxError(Belt.Option.getExn(Js.Exn.message(obj)))
Belt.Option.getExn(Js.Exn.message(obj)), ->SqError.fromMessageWithFrameStack(
Reducer_Peggy_Parse.syntaxErrorToLocation(obj)->Some, Reducer_FrameStack.makeSingleFrameStack(Reducer_Peggy_Parse.syntaxErrorToLocation(obj)),
)->Error )
->Error
} }

View File

@ -152,10 +152,7 @@ let parseIncludes = (this: t): t => {
} }
} }
let doRawParse = (this: t): T.rawParseArgumentType => let doRawParse = (this: t): T.rawParseArgumentType =>
this this->getSource->Reducer_Peggy_Parse.parse(this.sourceId)->E.R2.errMap(SqError.fromParseError)
->getSource
->Reducer_Peggy_Parse.parse(this.sourceId)
->E.R2.errMap(SqError.Message.fromParseError)
let rawParse = (this: t): t => let rawParse = (this: t): t =>
this->getRawParse->E.O2.defaultFn(() => doRawParse(this))->setRawParse(this, _) this->getRawParse->E.O2.defaultFn(() => doRawParse(this))->setRawParse(this, _)
@ -190,7 +187,7 @@ let doRun = (this: t, context: Reducer_T.context): t =>
} catch { } catch {
| e => this->failRun(e->SqError.fromException) | e => this->failRun(e->SqError.fromException)
} }
| Error(e) => this->failRun(e->SqError.fromMessage) | Error(e) => this->failRun(e)
} }
| None => this->failRun(RETodo("attempt to run without expression")->SqError.fromMessage) | None => this->failRun(RETodo("attempt to run without expression")->SqError.fromMessage)
} }

View File

@ -3,9 +3,9 @@ module ExpressionT = Reducer_Expression_T
type sourceArgumentType = string type sourceArgumentType = string
type sourceType = string type sourceType = string
type rawParseArgumentType = result<Parse.node, SqError.Message.t> type rawParseArgumentType = result<Parse.node, SqError.t>
type rawParseType = option<rawParseArgumentType> type rawParseType = option<rawParseArgumentType>
type expressionArgumentType = result<ExpressionT.t, SqError.Message.t> type expressionArgumentType = result<ExpressionT.t, SqError.t>
type expressionType = option<expressionArgumentType> type expressionType = option<expressionArgumentType>
type continuationArgumentType = Reducer_T.namespace type continuationArgumentType = Reducer_T.namespace
type continuationType = option<continuationArgumentType> type continuationType = option<continuationArgumentType>
@ -15,7 +15,7 @@ type resultType = option<resultArgumentType>
type continuesArgumentType = array<string> type continuesArgumentType = array<string>
type continuesType = array<string> type continuesType = array<string>
type includesArgumentType = string type includesArgumentType = string
type includesType = result<array<string>, SqError.Message.t> type includesType = result<array<string>, SqError.t>
type importAsVariablesType = array<(string, string)> type importAsVariablesType = array<(string, string)>
type projectItem = { type projectItem = {

View File

@ -19,7 +19,7 @@ module Message = {
| REOperationError(Operation.operationError) | REOperationError(Operation.operationError)
| RERecordPropertyNotFound(string, string) | RERecordPropertyNotFound(string, string)
| RESymbolNotFound(string) | RESymbolNotFound(string)
| RESyntaxError(string, option<location>) | RESyntaxError(string)
| RETodo(string) // To do | RETodo(string) // To do
| REUnitNotFound(string) | REUnitNotFound(string)
| RENeedToRun | RENeedToRun
@ -27,10 +27,6 @@ module Message = {
exception MessageException(t) exception MessageException(t)
let fromParseError = (
SyntaxError(message, location): Reducer_Peggy_Parse.parseError,
) => RESyntaxError(message, location->Some)
let toString = (err: t) => let toString = (err: t) =>
switch err { switch err {
| REArityError(_oFnName, arity, usedArity) => | REArityError(_oFnName, arity, usedArity) =>
@ -61,7 +57,7 @@ module Message = {
| 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, valueString) => `Expected type: ${typeName} but got: ${valueString}` | REExpectedType(typeName, valueString) => `Expected type: ${typeName} but got: ${valueString}`
| REUnitNotFound(unitName) => `Unit not found: ${unitName}` | REUnitNotFound(unitName) => `Unit not found: ${unitName}`
@ -106,6 +102,11 @@ let fromMessageWithFrameStack = (message: Message.t, frameStack: Reducer_FrameSt
let fromMessage = (message: Message.t) => let fromMessage = (message: Message.t) =>
fromMessageWithFrameStack(message, Reducer_FrameStack.make()) fromMessageWithFrameStack(message, Reducer_FrameStack.make())
let fromParseError = (SyntaxError(message, location): Reducer_Peggy_Parse.parseError) =>
RESyntaxError(message)->fromMessageWithFrameStack(
Reducer_FrameStack.makeSingleFrameStack(location),
)
@genType @genType
let getTopFrame = (t: t): option<Reducer_T.frame> => t.frameStack->Reducer_FrameStack.getTopFrame let getTopFrame = (t: t): option<Reducer_T.frame> => t.frameStack->Reducer_FrameStack.getTopFrame