locations for syntax errors
This commit is contained in:
parent
298492b3b8
commit
234ebe2103
|
@ -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))
|
||||||
|
|
|
@ -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", () => {
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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")
|
||||||
|
|
|
@ -65,3 +65,5 @@ and context = {
|
||||||
}
|
}
|
||||||
|
|
||||||
and reducerFn = (expression, context) => (value, context)
|
and reducerFn = (expression, context) => (value, context)
|
||||||
|
|
||||||
|
let topFrameName = "<top>"
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 = {
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user