include and "include as"
This commit is contained in:
parent
68ddf35387
commit
82a4e52384
|
@ -0,0 +1,27 @@
|
|||
@@warning("-44")
|
||||
module InternalExpressionValue = ReducerInterface_InternalExpressionValue
|
||||
module Bindings = Reducer_Bindings
|
||||
|
||||
open Jest
|
||||
open Expect
|
||||
open Expect.Operators
|
||||
|
||||
describe("Name Space", () => {
|
||||
let value = InternalExpressionValue.IEvNumber(1967.0)
|
||||
let nameSpace = Bindings.emptyNameSpace->Bindings.set("value", value)
|
||||
test("get", () => {
|
||||
expect(Bindings.get(nameSpace, "value")) == Some(value)
|
||||
})
|
||||
|
||||
test("chain and get", () => {
|
||||
let mainNameSpace = Bindings.emptyNameSpace->Bindings.chainTo([nameSpace])
|
||||
expect(Bindings.get(mainNameSpace, "value")) == Some(value)
|
||||
})
|
||||
|
||||
test("chain and set", () => {
|
||||
let mainNameSpace0 = Bindings.emptyNameSpace->Bindings.chainTo([nameSpace])
|
||||
let mainNameSpace =
|
||||
mainNameSpace0->Bindings.set("value", InternalExpressionValue.IEvNumber(1968.0))
|
||||
expect(Bindings.get(mainNameSpace, "value")) == Some(InternalExpressionValue.IEvNumber(1968.0))
|
||||
})
|
||||
})
|
|
@ -7,7 +7,7 @@ open Jest
|
|||
open Expect
|
||||
open Expect.Operators
|
||||
|
||||
Only.describe("Parse includes", () => {
|
||||
describe("Parse includes", () => {
|
||||
let project = Project.createProject()
|
||||
Project.setSource(
|
||||
project,
|
||||
|
@ -30,4 +30,92 @@ x=1`,
|
|||
| Error(error) => fail(error->Reducer_ErrorValue.errorToString)
|
||||
}
|
||||
})
|
||||
let internalProject = project->Project.T.Private.castToInternalProject
|
||||
test("past chain", () => {
|
||||
expect(Project.Private.getPastChain(internalProject, "main")) == ["common"]
|
||||
})
|
||||
test("import as variables", () => {
|
||||
expect(Project.Private.getIncludesAsVariables(internalProject, "main")) == []
|
||||
})
|
||||
})
|
||||
|
||||
describe("Parse includes", () => {
|
||||
let project = Project.createProject()
|
||||
Project.setSource(
|
||||
project,
|
||||
"main",
|
||||
`
|
||||
#include 'common'
|
||||
#include 'myModule' as myVariable
|
||||
x=1`,
|
||||
)
|
||||
Project.parseIncludes(project, "main")
|
||||
|
||||
test("dependencies", () => {
|
||||
expect(Project.getDependencies(project, "main")) == ["common", "myModule"]
|
||||
})
|
||||
|
||||
test("dependents", () => {
|
||||
expect(Project.getDependents(project, "main")) == []
|
||||
})
|
||||
|
||||
test("getIncludes", () => {
|
||||
let mainIncludes = Project.getIncludes(project, "main")
|
||||
switch mainIncludes {
|
||||
| Ok(includes) => expect(includes) == ["common", "myModule"]
|
||||
| Error(error) => fail(error->Reducer_ErrorValue.errorToString)
|
||||
}
|
||||
})
|
||||
|
||||
let internalProject = project->Project.T.Private.castToInternalProject
|
||||
|
||||
test("direct past chain", () => {
|
||||
expect(Project.Private.getPastChain(internalProject, "main")) == ["common"]
|
||||
})
|
||||
|
||||
test("direct includes", () => {
|
||||
expect(Project.Private.getDirectIncludes(internalProject, "main")) == ["common"]
|
||||
})
|
||||
|
||||
test("include as variables", () => {
|
||||
expect(Project.Private.getIncludesAsVariables(internalProject, "main")) == [
|
||||
("myVariable", "myModule"),
|
||||
]
|
||||
})
|
||||
})
|
||||
|
||||
describe("Parse multiple direct includes", () => {
|
||||
let project = Project.createProject()
|
||||
Project.setSource(
|
||||
project,
|
||||
"main",
|
||||
`
|
||||
#include 'common'
|
||||
#include 'common2'
|
||||
#include 'myModule' as myVariable
|
||||
x=1`,
|
||||
)
|
||||
Project.parseIncludes(project, "main")
|
||||
test("dependencies", () => {
|
||||
expect(Project.getDependencies(project, "main")) == ["common", "common2", "myModule"]
|
||||
})
|
||||
test("dependents", () => {
|
||||
expect(Project.getDependents(project, "main")) == []
|
||||
})
|
||||
test("getIncludes", () => {
|
||||
let mainIncludes = Project.getIncludes(project, "main")
|
||||
switch mainIncludes {
|
||||
| Ok(includes) => expect(includes) == ["common", "common2", "myModule"]
|
||||
| Error(error) => fail(error->Reducer_ErrorValue.errorToString)
|
||||
}
|
||||
})
|
||||
let internalProject = project->Project.T.Private.castToInternalProject
|
||||
test("direct past chain", () => {
|
||||
expect(Project.getPastChain(project, "main")) == ["common", "common2"]
|
||||
})
|
||||
test("include as variables", () => {
|
||||
expect(Project.Private.getIncludesAsVariables(internalProject, "main")) == [
|
||||
("myVariable", "myModule"),
|
||||
]
|
||||
})
|
||||
})
|
||||
|
|
|
@ -14,11 +14,9 @@ let runFetchResult = (project, sourceId) => {
|
|||
Project.getResult(project, sourceId)->InternalExpressionValue.toStringResult
|
||||
}
|
||||
|
||||
let runFetchBindings = (project, sourceId) => {
|
||||
let runFetchFlatBindings = (project, sourceId) => {
|
||||
Project.run(project, sourceId)
|
||||
Project.getBindings(project, sourceId)
|
||||
->InternalExpressionValue.IEvBindings
|
||||
->InternalExpressionValue.toString
|
||||
Project.getBindings(project, sourceId)->InternalExpressionValue.toStringBindings
|
||||
}
|
||||
|
||||
test("setting continuation", () => {
|
||||
|
@ -51,7 +49,7 @@ test("test library", () => {
|
|||
test("test bindings", () => {
|
||||
let project = Project.createProject()
|
||||
Project.setSource(project, "variables", "myVariable=666")
|
||||
runFetchBindings(project, "variables")->expect->toBe("@{myVariable: 666}")
|
||||
runFetchFlatBindings(project, "variables")->expect->toBe("@{myVariable: 666}")
|
||||
})
|
||||
|
||||
describe("project1", () => {
|
||||
|
@ -59,6 +57,7 @@ describe("project1", () => {
|
|||
Project.setSource(project, "first", "x=1")
|
||||
Project.setSource(project, "main", "x")
|
||||
Project.setContinues(project, "main", ["first"])
|
||||
let internalProject = project->Project.T.Private.castToInternalProject
|
||||
|
||||
test("runOrder", () => {
|
||||
expect(Project.getRunOrder(project)) == ["first", "main"]
|
||||
|
@ -75,11 +74,19 @@ describe("project1", () => {
|
|||
test("dependencies main", () => {
|
||||
expect(Project.getDependencies(project, "main")) == ["first"]
|
||||
})
|
||||
|
||||
test("past chain first", () => {
|
||||
expect(Project.Private.getPastChain(internalProject, "first")) == []
|
||||
})
|
||||
test("past chain main", () => {
|
||||
expect(Project.Private.getPastChain(internalProject, "main")) == ["first"]
|
||||
})
|
||||
|
||||
test("test result", () => {
|
||||
runFetchResult(project, "main")->expect->toBe("Ok(1)")
|
||||
})
|
||||
test("test bindings", () => {
|
||||
runFetchBindings(project, "main")->expect->toBe("@{x: 1}")
|
||||
runFetchFlatBindings(project, "first")->expect->toBe("@{x: 1}")
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -113,7 +120,7 @@ describe("project2", () => {
|
|||
runFetchResult(project, "main")->expect->toBe("Ok(2)")
|
||||
})
|
||||
test("test bindings", () => {
|
||||
runFetchBindings(project, "main")->expect->toBe("@{x: 1,y: 2}")
|
||||
runFetchFlatBindings(project, "main")->expect->toBe("@{x: 1,y: 2}")
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -169,6 +176,6 @@ describe("project with include", () => {
|
|||
runFetchResult(project, "main")->expect->toBe("Ok(2)")
|
||||
})
|
||||
test("test bindings", () => {
|
||||
runFetchBindings(project, "main")->expect->toBe("@{common: 0,x: 1,y: 2}")
|
||||
runFetchFlatBindings(project, "main")->expect->toBe("@{common: 0,x: 1,y: 2}")
|
||||
})
|
||||
})
|
||||
|
|
|
@ -153,4 +153,27 @@ Here we will finally proceed to a real life scenario. */
|
|||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("Includes myFile as myVariable", () => {
|
||||
/* Instead of including into global space you can also put a module into a record variable */
|
||||
let project = Project.createProject()
|
||||
Project.setSource(
|
||||
project,
|
||||
"main",
|
||||
`
|
||||
#include "common" as common
|
||||
x=1
|
||||
`,
|
||||
)
|
||||
Project.parseIncludes(project, "main")
|
||||
test("getDependencies", () => {
|
||||
Project.getDependencies(project, "main")->expect == ["common"]
|
||||
})
|
||||
test("getIncludes", () => {
|
||||
switch Project.getIncludes(project, "main") {
|
||||
| Ok(includes) => includes->expect == ["common"]
|
||||
| Error(err) => err->Reducer_ErrorValue.errorToString->fail
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -105,6 +105,11 @@ let getIncludes = (project: reducerProject, sourceId: string): result<
|
|||
reducerErrorValue,
|
||||
> => project->T.Private.castToInternalProject->Private.getIncludes(sourceId)
|
||||
|
||||
/* Other sources contributing to the global namespace of this source. */
|
||||
@genType
|
||||
let getPastChain = (project: reducerProject, sourceId: string): array<string> =>
|
||||
project->T.Private.castToInternalProject->Private.getPastChain(sourceId)
|
||||
|
||||
/*
|
||||
Answers the source codes after which this source code is continuing
|
||||
*/
|
||||
|
@ -183,7 +188,7 @@ let runAll = (project: reducerProject): unit =>
|
|||
project->T.Private.castToInternalProject->Private.runAll
|
||||
|
||||
/*
|
||||
Get the bindings after running this source file or the project
|
||||
Get the bindings after running this source fil. The bindings are local to the source
|
||||
*/
|
||||
@genType
|
||||
let getBindings = (project: reducerProject, sourceId: string): squiggleValue_Module =>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Only Bindings as the global module is supported
|
||||
// Other module operations such as import export will be prepreocessed jobs
|
||||
// Other module operations such as import export will be preprocessed jobs
|
||||
|
||||
module ExpressionT = Reducer_Expression_T
|
||||
module InternalExpressionValue = ReducerInterface_InternalExpressionValue
|
||||
|
@ -13,8 +13,7 @@ type t = ReducerInterface_InternalExpressionValue.nameSpace
|
|||
let typeAliasesKey = "_typeAliases_"
|
||||
let typeReferencesKey = "_typeReferences_"
|
||||
|
||||
let getType = (nameSpace: t, id: string) => {
|
||||
let NameSpace(container) = nameSpace
|
||||
let getType = (NameSpace(container): t, id: string) => {
|
||||
Belt.Map.String.get(container, typeAliasesKey)->Belt.Option.flatMap(aliases =>
|
||||
switch aliases {
|
||||
| IEvRecord(r) => Belt.Map.String.get(r, id)
|
||||
|
@ -23,8 +22,7 @@ let getType = (nameSpace: t, id: string) => {
|
|||
)
|
||||
}
|
||||
|
||||
let getTypeOf = (nameSpace: t, id: string) => {
|
||||
let NameSpace(container) = nameSpace
|
||||
let getTypeOf = (NameSpace(container): t, id: string) => {
|
||||
Belt.Map.String.get(container, typeReferencesKey)->Belt.Option.flatMap(defs =>
|
||||
switch defs {
|
||||
| IEvRecord(r) => Belt.Map.String.get(r, id)
|
||||
|
@ -33,44 +31,39 @@ let getTypeOf = (nameSpace: t, id: string) => {
|
|||
)
|
||||
}
|
||||
|
||||
let getWithDefault = (nameSpace: t, id: string, default) => {
|
||||
let NameSpace(container) = nameSpace
|
||||
Belt.Map.String.getWithDefault(container, id, default)
|
||||
}
|
||||
let getWithDefault = (NameSpace(container): t, id: string, default) =>
|
||||
switch Belt.Map.String.get(container, id) {
|
||||
| Some(v) => v
|
||||
| None => default
|
||||
}
|
||||
|
||||
let get = (nameSpace: t, id: string) => {
|
||||
let NameSpace(container) = nameSpace
|
||||
Belt.Map.String.get(container, id)
|
||||
}
|
||||
let get = (NameSpace(container): t, id: string) => Belt.Map.String.get(container, id)
|
||||
|
||||
let emptyMap: map = Belt.Map.String.empty
|
||||
|
||||
let setTypeAlias = (nameSpace: t, id: string, value): t => {
|
||||
let NameSpace(container) = nameSpace
|
||||
let setTypeAlias = (NameSpace(container): t, id: string, value): t => {
|
||||
let rValue = Belt.Map.String.getWithDefault(container, typeAliasesKey, IEvRecord(emptyMap))
|
||||
let r = switch rValue {
|
||||
| IEvRecord(r) => r
|
||||
| _ => emptyMap
|
||||
}
|
||||
let r2 = Belt.Map.String.set(r, id, value)->IEvRecord
|
||||
Belt.Map.String.set(container, typeAliasesKey, r2)->NameSpace
|
||||
NameSpace(Belt.Map.String.set(container, typeAliasesKey, r2))
|
||||
}
|
||||
|
||||
let setTypeOf = (nameSpace: t, id: string, value): t => {
|
||||
let NameSpace(container) = nameSpace
|
||||
let setTypeOf = (NameSpace(container): t, id: string, value): t => {
|
||||
let rValue = Belt.Map.String.getWithDefault(container, typeReferencesKey, IEvRecord(emptyMap))
|
||||
let r = switch rValue {
|
||||
| IEvRecord(r) => r
|
||||
| _ => emptyMap
|
||||
}
|
||||
let r2 = Belt.Map.String.set(r, id, value)->IEvRecord
|
||||
Belt.Map.String.set(container, typeReferencesKey, r2)->NameSpace
|
||||
NameSpace(Belt.Map.String.set(container, typeReferencesKey, r2))
|
||||
}
|
||||
|
||||
let set = (nameSpace: t, id: string, value): t => {
|
||||
let NameSpace(container) = nameSpace
|
||||
Belt.Map.String.set(container, id, value)->NameSpace
|
||||
}
|
||||
let set = (NameSpace(container): t, id: string, value): t => NameSpace(
|
||||
Belt.Map.String.set(container, id, value),
|
||||
)
|
||||
|
||||
let emptyModule: t = NameSpace(emptyMap)
|
||||
let emptyBindings = emptyModule
|
||||
|
@ -86,29 +79,28 @@ let fromExpressionValue = (aValue: internalExpressionValue): t =>
|
|||
| _ => emptyModule
|
||||
}
|
||||
|
||||
let fromArray = a => Belt.Map.String.fromArray(a)->NameSpace
|
||||
let fromArray = a => NameSpace(Belt.Map.String.fromArray(a))
|
||||
|
||||
let merge = (nameSpace: t, other: t): t => {
|
||||
let NameSpace(container) = nameSpace
|
||||
let NameSpace(otherContainer) = other
|
||||
otherContainer
|
||||
->Belt.Map.String.reduce(container, (container, key, value) =>
|
||||
let mergeFrom = (NameSpace(container): t, NameSpace(newContainer): t): t => {
|
||||
NameSpace(
|
||||
newContainer->Belt.Map.String.reduce(container, (container, key, value) =>
|
||||
Belt.Map.String.set(container, key, value)
|
||||
),
|
||||
)
|
||||
->NameSpace
|
||||
}
|
||||
|
||||
let removeOther = (nameSpace: t, other: t): t => {
|
||||
let NameSpace(container) = nameSpace
|
||||
let NameSpace(otherContainer) = other
|
||||
let removeOther = (NameSpace(container): t, NameSpace(otherContainer): t): t => {
|
||||
let keys = Belt.Map.String.keysToArray(otherContainer)
|
||||
NameSpace(
|
||||
Belt.Map.String.keep(container, (key, _value) => {
|
||||
let removeThis = Js.Array2.includes(keys, key)
|
||||
!removeThis
|
||||
})->NameSpace
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
external castExpressionToInternalCode: ExpressionT.expressionOrFFI => internalCode = "%identity"
|
||||
|
||||
let eLambdaFFIValue = (ffiFn: ExpressionT.ffiFn) => {
|
||||
IEvLambda({
|
||||
parameters: [],
|
||||
|
@ -153,9 +145,8 @@ let convertOptionToFfiFn = (
|
|||
}
|
||||
|
||||
// -- Module definition
|
||||
let define = (nameSpace: t, identifier: string, ev: internalExpressionValue): t => {
|
||||
let NameSpace(container) = nameSpace
|
||||
Belt.Map.String.set(container, identifier, ev)->NameSpace
|
||||
let define = (NameSpace(container): t, identifier: string, ev: internalExpressionValue): t => {
|
||||
NameSpace(Belt.Map.String.set(container, identifier, ev))
|
||||
}
|
||||
|
||||
let defineNumber = (nameSpace: t, identifier: string, value: float): t =>
|
||||
|
@ -186,3 +177,9 @@ let defineFunctionReturningResult = (
|
|||
}
|
||||
|
||||
let emptyStdLib: t = emptyModule->defineBool("_standardLibrary", true)
|
||||
|
||||
let chainTo = (nameSpace: t, previousNameSpaces: array<t>) => {
|
||||
previousNameSpaces->Belt.Array.reduce(nameSpace, (topNameSpace, prevNameSpace) =>
|
||||
mergeFrom(prevNameSpace, topNameSpace)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -21,8 +21,7 @@ let inspectOption = (oNameSpace, label: string) =>
|
|||
}
|
||||
|
||||
let minus = (NameSpace(thisContainer): t, NameSpace(thatContainer): t) => {
|
||||
Belt.Map.String.removeMany(
|
||||
thisContainer,
|
||||
Belt.Map.String.keysToArray(thatContainer),
|
||||
)->InternalExpressionValue.NameSpace
|
||||
InternalExpressionValue.NameSpace(
|
||||
Belt.Map.String.removeMany(thisContainer, Belt.Map.String.keysToArray(thatContainer)),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -83,6 +83,21 @@ module Private = {
|
|||
let getIncludes = (project: t, sourceId: string): ProjectItem.T.includesType =>
|
||||
project->getItem(sourceId)->ProjectItem.getIncludes
|
||||
|
||||
// let getDirectIncludes = (project: t, sourceId: string): array<string> =>
|
||||
// project->getItem(sourceId)->ProjectItem.getDirectIncludes
|
||||
|
||||
let getPastChain = (project: t, sourceId: string): array<string> =>
|
||||
project->getItem(sourceId)->ProjectItem.getPastChain
|
||||
|
||||
let getIncludesAsVariables = (
|
||||
project: t,
|
||||
sourceId: string,
|
||||
): ProjectItem.T.importAsVariablesType =>
|
||||
project->getItem(sourceId)->ProjectItem.getIncludesAsVariables
|
||||
|
||||
let getDirectIncludes = (project: t, sourceId: string): array<string> =>
|
||||
project->getItem(sourceId)->ProjectItem.getDirectIncludes
|
||||
|
||||
let setContinues = (project: t, sourceId: string, continues: array<string>): unit => {
|
||||
let newItem = project->getItem(sourceId)->ProjectItem.setContinues(continues)
|
||||
Belt.Map.String.set(project["items"], sourceId, newItem)->T.Private.setFieldItems(project, _)
|
||||
|
@ -155,39 +170,63 @@ module Private = {
|
|||
environment: getEnvironment(project),
|
||||
}
|
||||
|
||||
let doRunWithContinuation = (
|
||||
project: t,
|
||||
sourceId: string,
|
||||
continuation: ProjectItem.T.continuation,
|
||||
): unit => {
|
||||
let getContinuationsBefore = (project: t, sourceId: string): array<
|
||||
ProjectItem.T.continuation,
|
||||
> => {
|
||||
let pastNameSpaces = project->getPastChain(sourceId)->Belt.Array.map(getBindings(project, _))
|
||||
let theLength = Belt.Array.length(pastNameSpaces)
|
||||
if theLength == 0 {
|
||||
// `getContinuationBefore ${sourceId}: stdLib`->Js.log
|
||||
[project->getStdLib]
|
||||
} else {
|
||||
// `getContinuationBefore ${sourceId}: ${lastOne} = ${InternalExpressionValue.toStringBindings(
|
||||
// project->getBindings(lastOne),
|
||||
// )}`->Js.log
|
||||
pastNameSpaces
|
||||
}
|
||||
}
|
||||
|
||||
let linkDependencies = (project: t, sourceId: string): ProjectItem.T.continuation => {
|
||||
module NameSpace = Reducer_Bindings
|
||||
let continuationsBefore = project->getContinuationsBefore(sourceId)
|
||||
let nameSpace = NameSpace.emptyNameSpace->NameSpace.chainTo(continuationsBefore)
|
||||
let includesAsVariables = project->getIncludesAsVariables(sourceId)
|
||||
Belt.Array.reduce(includesAsVariables, nameSpace, (currentNameSpace, (variable, includeFile)) =>
|
||||
Bindings.set(
|
||||
currentNameSpace,
|
||||
variable,
|
||||
getBindings(project, includeFile)->InternalExpressionValue.IEvBindings,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
let doLinkAndRun = (project: t, sourceId: string): unit => {
|
||||
let accessors = buildProjectAccessors(project)
|
||||
let states = accessors.states
|
||||
let continuation = linkDependencies(project, sourceId)
|
||||
let newItem = project->getItem(sourceId)->ProjectItem.run(continuation, accessors)
|
||||
Belt.Map.String.set(project["items"], sourceId, newItem)->T.Private.setFieldItems(project, _)
|
||||
setContinuation(project, sourceId, states.continuation)
|
||||
}
|
||||
|
||||
type runState = (ProjectItem.T.resultArgumentType, ProjectItem.T.continuation)
|
||||
type runState = ProjectItem.T.resultArgumentType
|
||||
|
||||
let tryRunWithContinuation = (
|
||||
let tryRunWithResult = (
|
||||
project: t,
|
||||
sourceId: string,
|
||||
(rPrevResult: ProjectItem.T.resultArgumentType, continuation: ProjectItem.T.continuation),
|
||||
): (ProjectItem.T.resultArgumentType, ProjectItem.T.continuation) => {
|
||||
rPrevResult: ProjectItem.T.resultArgumentType,
|
||||
): ProjectItem.T.resultArgumentType => {
|
||||
switch getResultOption(project, sourceId) {
|
||||
| Some(result) => (result, getContinuation(project, sourceId)) // already ran
|
||||
| Some(result) => result // already ran
|
||||
| None =>
|
||||
switch rPrevResult {
|
||||
| Error(error) => {
|
||||
setResult(project, sourceId, Error(error))
|
||||
(Error(error), continuation)
|
||||
Error(error)
|
||||
}
|
||||
| Ok(_prevResult) => {
|
||||
doRunWithContinuation(project, sourceId, continuation)
|
||||
(
|
||||
getResultOption(project, sourceId)->Belt.Option.getWithDefault(rPrevResult),
|
||||
getContinuation(project, sourceId),
|
||||
)
|
||||
doLinkAndRun(project, sourceId)
|
||||
getResultOption(project, sourceId)->Belt.Option.getWithDefault(rPrevResult)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -195,17 +234,17 @@ module Private = {
|
|||
|
||||
let runAll = (project: t): unit => {
|
||||
let runOrder = Topology.getRunOrder(project)
|
||||
let initialState = (Ok(InternalExpressionValue.IEvVoid), getStdLib(project))
|
||||
let initialState = Ok(InternalExpressionValue.IEvVoid)
|
||||
let _finalState = Belt.Array.reduce(runOrder, initialState, (currState, currId) =>
|
||||
tryRunWithContinuation(project, currId, currState)
|
||||
tryRunWithResult(project, currId, currState)
|
||||
)
|
||||
}
|
||||
|
||||
let run = (project: t, sourceId: string): unit => {
|
||||
let runOrder = Topology.getRunOrderFor(project, sourceId)
|
||||
let initialState = (Ok(InternalExpressionValue.IEvVoid), getStdLib(project))
|
||||
let initialState = Ok(InternalExpressionValue.IEvVoid)
|
||||
let _finalState = Belt.Array.reduce(runOrder, initialState, (currState, currId) =>
|
||||
tryRunWithContinuation(project, currId, currState)
|
||||
tryRunWithResult(project, currId, currState)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -173,12 +173,14 @@ function peg$parse(input, options) {
|
|||
var peg$startRuleFunctions = { start: peg$parsestart };
|
||||
var peg$startRuleFunction = peg$parsestart;
|
||||
|
||||
var peg$c0 = "#include";
|
||||
var peg$c1 = "'";
|
||||
var peg$c2 = "\"";
|
||||
var peg$c3 = "//";
|
||||
var peg$c4 = "/*";
|
||||
var peg$c5 = "*/";
|
||||
var peg$c0 = "#";
|
||||
var peg$c1 = "#include";
|
||||
var peg$c2 = "as";
|
||||
var peg$c3 = "'";
|
||||
var peg$c4 = "\"";
|
||||
var peg$c5 = "//";
|
||||
var peg$c6 = "/*";
|
||||
var peg$c7 = "*/";
|
||||
|
||||
var peg$r0 = /^[^']/;
|
||||
var peg$r1 = /^[^"]/;
|
||||
|
@ -186,29 +188,40 @@ function peg$parse(input, options) {
|
|||
var peg$r3 = /^[ \t]/;
|
||||
var peg$r4 = /^[\n\r]/;
|
||||
var peg$r5 = /^[^\r\n]/;
|
||||
var peg$r6 = /^[_a-z]/;
|
||||
var peg$r7 = /^[_a-z0-9]/i;
|
||||
|
||||
var peg$e0 = peg$literalExpectation("#include", false);
|
||||
var peg$e1 = peg$otherExpectation("string");
|
||||
var peg$e2 = peg$literalExpectation("'", false);
|
||||
var peg$e3 = peg$classExpectation(["'"], true, false);
|
||||
var peg$e4 = peg$literalExpectation("\"", false);
|
||||
var peg$e5 = peg$classExpectation(["\""], true, false);
|
||||
var peg$e6 = peg$literalExpectation("//", false);
|
||||
var peg$e7 = peg$literalExpectation("/*", false);
|
||||
var peg$e8 = peg$classExpectation(["*"], true, false);
|
||||
var peg$e9 = peg$literalExpectation("*/", false);
|
||||
var peg$e10 = peg$otherExpectation("white space");
|
||||
var peg$e11 = peg$classExpectation([" ", "\t"], false, false);
|
||||
var peg$e12 = peg$otherExpectation("newline");
|
||||
var peg$e13 = peg$classExpectation(["\n", "\r"], false, false);
|
||||
var peg$e14 = peg$classExpectation(["\r", "\n"], true, false);
|
||||
var peg$e0 = peg$literalExpectation("#", false);
|
||||
var peg$e1 = peg$literalExpectation("#include", false);
|
||||
var peg$e2 = peg$literalExpectation("as", false);
|
||||
var peg$e3 = peg$otherExpectation("string");
|
||||
var peg$e4 = peg$literalExpectation("'", false);
|
||||
var peg$e5 = peg$classExpectation(["'"], true, false);
|
||||
var peg$e6 = peg$literalExpectation("\"", false);
|
||||
var peg$e7 = peg$classExpectation(["\""], true, false);
|
||||
var peg$e8 = peg$otherExpectation("comment");
|
||||
var peg$e9 = peg$literalExpectation("//", false);
|
||||
var peg$e10 = peg$literalExpectation("/*", false);
|
||||
var peg$e11 = peg$classExpectation(["*"], true, false);
|
||||
var peg$e12 = peg$literalExpectation("*/", false);
|
||||
var peg$e13 = peg$otherExpectation("white space");
|
||||
var peg$e14 = peg$classExpectation([" ", "\t"], false, false);
|
||||
var peg$e15 = peg$otherExpectation("newline");
|
||||
var peg$e16 = peg$classExpectation(["\n", "\r"], false, false);
|
||||
var peg$e17 = peg$otherExpectation("code");
|
||||
var peg$e18 = peg$classExpectation(["\r", "\n"], true, false);
|
||||
var peg$e19 = peg$otherExpectation("identifier");
|
||||
var peg$e20 = peg$classExpectation(["_", ["a", "z"]], false, false);
|
||||
var peg$e21 = peg$classExpectation(["_", ["a", "z"], ["0", "9"]], false, true);
|
||||
|
||||
var peg$f0 = function(head, tail) {return [head, ...tail].filter( e => e != '');};
|
||||
var peg$f1 = function() {return [];};
|
||||
var peg$f2 = function(characters) {return characters.join('');};
|
||||
var peg$f2 = function(file, variable) {return [!variable ? '' : variable, file]};
|
||||
var peg$f3 = function(characters) {return characters.join('');};
|
||||
var peg$f4 = function() { return '';};
|
||||
var peg$f4 = function(characters) {return characters.join('');};
|
||||
var peg$f5 = function() { return '';};
|
||||
var peg$f6 = function() { return '';};
|
||||
var peg$f7 = function() {return text();};
|
||||
var peg$currPos = 0;
|
||||
var peg$savedPos = 0;
|
||||
var peg$posDetailsCache = [{ line: 1, column: 1 }];
|
||||
|
@ -369,7 +382,7 @@ function peg$parse(input, options) {
|
|||
function peg$parsestart() {
|
||||
var s0, s1, s2, s3, s4;
|
||||
|
||||
var key = peg$currPos * 10 + 0;
|
||||
var key = peg$currPos * 12 + 0;
|
||||
var cached = peg$resultsCache[key];
|
||||
|
||||
if (cached) {
|
||||
|
@ -426,7 +439,7 @@ function peg$parse(input, options) {
|
|||
function peg$parseincludes() {
|
||||
var s0, s1, s2, s3, s4, s5;
|
||||
|
||||
var key = peg$currPos * 10 + 1;
|
||||
var key = peg$currPos * 12 + 1;
|
||||
var cached = peg$resultsCache[key];
|
||||
|
||||
if (cached) {
|
||||
|
@ -436,7 +449,7 @@ function peg$parse(input, options) {
|
|||
}
|
||||
|
||||
s0 = peg$currPos;
|
||||
s1 = peg$parseincludeStatement();
|
||||
s1 = peg$parsedependencyStatement();
|
||||
if (s1 !== peg$FAILED) {
|
||||
s2 = [];
|
||||
s3 = peg$currPos;
|
||||
|
@ -451,7 +464,7 @@ function peg$parse(input, options) {
|
|||
s4 = peg$FAILED;
|
||||
}
|
||||
if (s4 !== peg$FAILED) {
|
||||
s5 = peg$parseincludeStatement();
|
||||
s5 = peg$parsedependencyStatement();
|
||||
if (s5 !== peg$FAILED) {
|
||||
s3 = s5;
|
||||
} else {
|
||||
|
@ -476,7 +489,7 @@ function peg$parse(input, options) {
|
|||
s4 = peg$FAILED;
|
||||
}
|
||||
if (s4 !== peg$FAILED) {
|
||||
s5 = peg$parseincludeStatement();
|
||||
s5 = peg$parsedependencyStatement();
|
||||
if (s5 !== peg$FAILED) {
|
||||
s3 = s5;
|
||||
} else {
|
||||
|
@ -496,9 +509,26 @@ function peg$parse(input, options) {
|
|||
}
|
||||
if (s0 === peg$FAILED) {
|
||||
s0 = peg$currPos;
|
||||
s1 = peg$parseignore();
|
||||
s1 = peg$currPos;
|
||||
peg$silentFails++;
|
||||
if (input.charCodeAt(peg$currPos) === 35) {
|
||||
s2 = peg$c0;
|
||||
peg$currPos++;
|
||||
} else {
|
||||
s2 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e0); }
|
||||
}
|
||||
peg$silentFails--;
|
||||
if (s2 === peg$FAILED) {
|
||||
s1 = undefined;
|
||||
} else {
|
||||
peg$currPos = s1;
|
||||
s1 = peg$FAILED;
|
||||
}
|
||||
if (s1 !== peg$FAILED) {
|
||||
peg$savedPos = s0;
|
||||
s1 = peg$f1();
|
||||
}
|
||||
s0 = s1;
|
||||
}
|
||||
|
||||
|
@ -507,10 +537,35 @@ function peg$parse(input, options) {
|
|||
return s0;
|
||||
}
|
||||
|
||||
function peg$parseincludeStatement() {
|
||||
var s0, s1, s2, s3, s4, s5, s6;
|
||||
function peg$parsedependencyStatement() {
|
||||
var s0;
|
||||
|
||||
var key = peg$currPos * 10 + 2;
|
||||
var key = peg$currPos * 12 + 2;
|
||||
var cached = peg$resultsCache[key];
|
||||
|
||||
if (cached) {
|
||||
peg$currPos = cached.nextPos;
|
||||
|
||||
return cached.result;
|
||||
}
|
||||
|
||||
s0 = peg$parseincludeStatement();
|
||||
if (s0 === peg$FAILED) {
|
||||
s0 = peg$parsecomment();
|
||||
if (s0 === peg$FAILED) {
|
||||
s0 = peg$parsedelimitedComment();
|
||||
}
|
||||
}
|
||||
|
||||
peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
|
||||
|
||||
return s0;
|
||||
}
|
||||
|
||||
function peg$parseincludeStatement() {
|
||||
var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9;
|
||||
|
||||
var key = peg$currPos * 12 + 3;
|
||||
var cached = peg$resultsCache[key];
|
||||
|
||||
if (cached) {
|
||||
|
@ -526,29 +581,99 @@ function peg$parse(input, options) {
|
|||
s1.push(s2);
|
||||
s2 = peg$parse_();
|
||||
}
|
||||
if (input.substr(peg$currPos, 8) === peg$c0) {
|
||||
s2 = peg$c0;
|
||||
if (input.substr(peg$currPos, 8) === peg$c1) {
|
||||
s2 = peg$c1;
|
||||
peg$currPos += 8;
|
||||
} else {
|
||||
s2 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e0); }
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e1); }
|
||||
}
|
||||
if (s2 !== peg$FAILED) {
|
||||
s3 = [];
|
||||
s4 = peg$parse_();
|
||||
if (s4 !== peg$FAILED) {
|
||||
while (s4 !== peg$FAILED) {
|
||||
s3.push(s4);
|
||||
s4 = peg$parse_();
|
||||
}
|
||||
} else {
|
||||
s3 = peg$FAILED;
|
||||
}
|
||||
if (s3 !== peg$FAILED) {
|
||||
s4 = peg$parsestring();
|
||||
if (s4 !== peg$FAILED) {
|
||||
s5 = [];
|
||||
s6 = peg$parse_();
|
||||
while (s6 !== peg$FAILED) {
|
||||
s5.push(s6);
|
||||
s6 = peg$parse_();
|
||||
s5 = peg$currPos;
|
||||
s6 = [];
|
||||
s7 = peg$parse_();
|
||||
if (s7 !== peg$FAILED) {
|
||||
while (s7 !== peg$FAILED) {
|
||||
s6.push(s7);
|
||||
s7 = peg$parse_();
|
||||
}
|
||||
s0 = s4;
|
||||
} else {
|
||||
s6 = peg$FAILED;
|
||||
}
|
||||
if (s6 !== peg$FAILED) {
|
||||
if (input.substr(peg$currPos, 2) === peg$c2) {
|
||||
s7 = peg$c2;
|
||||
peg$currPos += 2;
|
||||
} else {
|
||||
s7 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e2); }
|
||||
}
|
||||
if (s7 !== peg$FAILED) {
|
||||
s8 = [];
|
||||
s9 = peg$parse_();
|
||||
if (s9 !== peg$FAILED) {
|
||||
while (s9 !== peg$FAILED) {
|
||||
s8.push(s9);
|
||||
s9 = peg$parse_();
|
||||
}
|
||||
} else {
|
||||
s8 = peg$FAILED;
|
||||
}
|
||||
if (s8 !== peg$FAILED) {
|
||||
s9 = peg$parseidentifier();
|
||||
if (s9 !== peg$FAILED) {
|
||||
s5 = s9;
|
||||
} else {
|
||||
peg$currPos = s5;
|
||||
s5 = peg$FAILED;
|
||||
}
|
||||
} else {
|
||||
peg$currPos = s5;
|
||||
s5 = peg$FAILED;
|
||||
}
|
||||
} else {
|
||||
peg$currPos = s5;
|
||||
s5 = peg$FAILED;
|
||||
}
|
||||
} else {
|
||||
peg$currPos = s5;
|
||||
s5 = peg$FAILED;
|
||||
}
|
||||
if (s5 === peg$FAILED) {
|
||||
s5 = null;
|
||||
}
|
||||
s6 = [];
|
||||
s7 = peg$parse_();
|
||||
while (s7 !== peg$FAILED) {
|
||||
s6.push(s7);
|
||||
s7 = peg$parse_();
|
||||
}
|
||||
s7 = peg$currPos;
|
||||
peg$silentFails++;
|
||||
s8 = peg$parsenewLine();
|
||||
peg$silentFails--;
|
||||
if (s8 !== peg$FAILED) {
|
||||
peg$currPos = s7;
|
||||
s7 = undefined;
|
||||
} else {
|
||||
s7 = peg$FAILED;
|
||||
}
|
||||
if (s7 !== peg$FAILED) {
|
||||
peg$savedPos = s0;
|
||||
s0 = peg$f2(s4, s5);
|
||||
} else {
|
||||
peg$currPos = s0;
|
||||
s0 = peg$FAILED;
|
||||
|
@ -557,11 +682,13 @@ function peg$parse(input, options) {
|
|||
peg$currPos = s0;
|
||||
s0 = peg$FAILED;
|
||||
}
|
||||
if (s0 === peg$FAILED) {
|
||||
s0 = peg$parsecomment();
|
||||
if (s0 === peg$FAILED) {
|
||||
s0 = peg$parsedelimitedComment();
|
||||
} else {
|
||||
peg$currPos = s0;
|
||||
s0 = peg$FAILED;
|
||||
}
|
||||
} else {
|
||||
peg$currPos = s0;
|
||||
s0 = peg$FAILED;
|
||||
}
|
||||
|
||||
peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
|
||||
|
@ -572,7 +699,7 @@ function peg$parse(input, options) {
|
|||
function peg$parsestring() {
|
||||
var s0, s1, s2, s3, s4;
|
||||
|
||||
var key = peg$currPos * 10 + 3;
|
||||
var key = peg$currPos * 12 + 4;
|
||||
var cached = peg$resultsCache[key];
|
||||
|
||||
if (cached) {
|
||||
|
@ -585,58 +712,7 @@ function peg$parse(input, options) {
|
|||
s0 = peg$currPos;
|
||||
s1 = peg$currPos;
|
||||
if (input.charCodeAt(peg$currPos) === 39) {
|
||||
s2 = peg$c1;
|
||||
peg$currPos++;
|
||||
} else {
|
||||
s2 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e2); }
|
||||
}
|
||||
if (s2 !== peg$FAILED) {
|
||||
s3 = [];
|
||||
if (peg$r0.test(input.charAt(peg$currPos))) {
|
||||
s4 = input.charAt(peg$currPos);
|
||||
peg$currPos++;
|
||||
} else {
|
||||
s4 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e3); }
|
||||
}
|
||||
while (s4 !== peg$FAILED) {
|
||||
s3.push(s4);
|
||||
if (peg$r0.test(input.charAt(peg$currPos))) {
|
||||
s4 = input.charAt(peg$currPos);
|
||||
peg$currPos++;
|
||||
} else {
|
||||
s4 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e3); }
|
||||
}
|
||||
}
|
||||
if (input.charCodeAt(peg$currPos) === 39) {
|
||||
s4 = peg$c1;
|
||||
peg$currPos++;
|
||||
} else {
|
||||
s4 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e2); }
|
||||
}
|
||||
if (s4 !== peg$FAILED) {
|
||||
s1 = s3;
|
||||
} else {
|
||||
peg$currPos = s1;
|
||||
s1 = peg$FAILED;
|
||||
}
|
||||
} else {
|
||||
peg$currPos = s1;
|
||||
s1 = peg$FAILED;
|
||||
}
|
||||
if (s1 !== peg$FAILED) {
|
||||
peg$savedPos = s0;
|
||||
s1 = peg$f2(s1);
|
||||
}
|
||||
s0 = s1;
|
||||
if (s0 === peg$FAILED) {
|
||||
s0 = peg$currPos;
|
||||
s1 = peg$currPos;
|
||||
if (input.charCodeAt(peg$currPos) === 34) {
|
||||
s2 = peg$c2;
|
||||
s2 = peg$c3;
|
||||
peg$currPos++;
|
||||
} else {
|
||||
s2 = peg$FAILED;
|
||||
|
@ -644,7 +720,7 @@ function peg$parse(input, options) {
|
|||
}
|
||||
if (s2 !== peg$FAILED) {
|
||||
s3 = [];
|
||||
if (peg$r1.test(input.charAt(peg$currPos))) {
|
||||
if (peg$r0.test(input.charAt(peg$currPos))) {
|
||||
s4 = input.charAt(peg$currPos);
|
||||
peg$currPos++;
|
||||
} else {
|
||||
|
@ -653,7 +729,7 @@ function peg$parse(input, options) {
|
|||
}
|
||||
while (s4 !== peg$FAILED) {
|
||||
s3.push(s4);
|
||||
if (peg$r1.test(input.charAt(peg$currPos))) {
|
||||
if (peg$r0.test(input.charAt(peg$currPos))) {
|
||||
s4 = input.charAt(peg$currPos);
|
||||
peg$currPos++;
|
||||
} else {
|
||||
|
@ -661,8 +737,8 @@ function peg$parse(input, options) {
|
|||
if (peg$silentFails === 0) { peg$fail(peg$e5); }
|
||||
}
|
||||
}
|
||||
if (input.charCodeAt(peg$currPos) === 34) {
|
||||
s4 = peg$c2;
|
||||
if (input.charCodeAt(peg$currPos) === 39) {
|
||||
s4 = peg$c3;
|
||||
peg$currPos++;
|
||||
} else {
|
||||
s4 = peg$FAILED;
|
||||
|
@ -683,11 +759,62 @@ function peg$parse(input, options) {
|
|||
s1 = peg$f3(s1);
|
||||
}
|
||||
s0 = s1;
|
||||
if (s0 === peg$FAILED) {
|
||||
s0 = peg$currPos;
|
||||
s1 = peg$currPos;
|
||||
if (input.charCodeAt(peg$currPos) === 34) {
|
||||
s2 = peg$c4;
|
||||
peg$currPos++;
|
||||
} else {
|
||||
s2 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e6); }
|
||||
}
|
||||
if (s2 !== peg$FAILED) {
|
||||
s3 = [];
|
||||
if (peg$r1.test(input.charAt(peg$currPos))) {
|
||||
s4 = input.charAt(peg$currPos);
|
||||
peg$currPos++;
|
||||
} else {
|
||||
s4 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e7); }
|
||||
}
|
||||
while (s4 !== peg$FAILED) {
|
||||
s3.push(s4);
|
||||
if (peg$r1.test(input.charAt(peg$currPos))) {
|
||||
s4 = input.charAt(peg$currPos);
|
||||
peg$currPos++;
|
||||
} else {
|
||||
s4 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e7); }
|
||||
}
|
||||
}
|
||||
if (input.charCodeAt(peg$currPos) === 34) {
|
||||
s4 = peg$c4;
|
||||
peg$currPos++;
|
||||
} else {
|
||||
s4 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e6); }
|
||||
}
|
||||
if (s4 !== peg$FAILED) {
|
||||
s1 = s3;
|
||||
} else {
|
||||
peg$currPos = s1;
|
||||
s1 = peg$FAILED;
|
||||
}
|
||||
} else {
|
||||
peg$currPos = s1;
|
||||
s1 = peg$FAILED;
|
||||
}
|
||||
if (s1 !== peg$FAILED) {
|
||||
peg$savedPos = s0;
|
||||
s1 = peg$f4(s1);
|
||||
}
|
||||
s0 = s1;
|
||||
}
|
||||
peg$silentFails--;
|
||||
if (s0 === peg$FAILED) {
|
||||
s1 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e1); }
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e3); }
|
||||
}
|
||||
|
||||
peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
|
||||
|
@ -698,7 +825,7 @@ function peg$parse(input, options) {
|
|||
function peg$parseignore() {
|
||||
var s0, s1;
|
||||
|
||||
var key = peg$currPos * 10 + 4;
|
||||
var key = peg$currPos * 12 + 5;
|
||||
var cached = peg$resultsCache[key];
|
||||
|
||||
if (cached) {
|
||||
|
@ -732,9 +859,9 @@ function peg$parse(input, options) {
|
|||
}
|
||||
|
||||
function peg$parsecomment() {
|
||||
var s0, s1, s2, s3;
|
||||
var s0, s1, s2, s3, s4;
|
||||
|
||||
var key = peg$currPos * 10 + 5;
|
||||
var key = peg$currPos * 12 + 6;
|
||||
var cached = peg$resultsCache[key];
|
||||
|
||||
if (cached) {
|
||||
|
@ -743,79 +870,32 @@ function peg$parse(input, options) {
|
|||
return cached.result;
|
||||
}
|
||||
|
||||
peg$silentFails++;
|
||||
s0 = peg$currPos;
|
||||
if (input.substr(peg$currPos, 2) === peg$c3) {
|
||||
s1 = peg$c3;
|
||||
peg$currPos += 2;
|
||||
} else {
|
||||
s1 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e6); }
|
||||
}
|
||||
if (s1 !== peg$FAILED) {
|
||||
s2 = [];
|
||||
s3 = peg$parseany();
|
||||
while (s3 !== peg$FAILED) {
|
||||
s2.push(s3);
|
||||
s3 = peg$parseany();
|
||||
}
|
||||
peg$savedPos = s0;
|
||||
s0 = peg$f4();
|
||||
} else {
|
||||
peg$currPos = s0;
|
||||
s0 = peg$FAILED;
|
||||
}
|
||||
|
||||
peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
|
||||
|
||||
return s0;
|
||||
}
|
||||
|
||||
function peg$parsedelimitedComment() {
|
||||
var s0, s1, s2, s3;
|
||||
|
||||
var key = peg$currPos * 10 + 6;
|
||||
var cached = peg$resultsCache[key];
|
||||
|
||||
if (cached) {
|
||||
peg$currPos = cached.nextPos;
|
||||
|
||||
return cached.result;
|
||||
}
|
||||
|
||||
s0 = peg$currPos;
|
||||
if (input.substr(peg$currPos, 2) === peg$c4) {
|
||||
s1 = peg$c4;
|
||||
peg$currPos += 2;
|
||||
} else {
|
||||
s1 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e7); }
|
||||
}
|
||||
if (s1 !== peg$FAILED) {
|
||||
s2 = [];
|
||||
if (peg$r2.test(input.charAt(peg$currPos))) {
|
||||
s3 = input.charAt(peg$currPos);
|
||||
peg$currPos++;
|
||||
} else {
|
||||
s3 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e8); }
|
||||
}
|
||||
while (s3 !== peg$FAILED) {
|
||||
s2.push(s3);
|
||||
if (peg$r2.test(input.charAt(peg$currPos))) {
|
||||
s3 = input.charAt(peg$currPos);
|
||||
peg$currPos++;
|
||||
} else {
|
||||
s3 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e8); }
|
||||
}
|
||||
}
|
||||
if (input.substr(peg$currPos, 2) === peg$c5) {
|
||||
s3 = peg$c5;
|
||||
s1 = peg$c5;
|
||||
peg$currPos += 2;
|
||||
} else {
|
||||
s3 = peg$FAILED;
|
||||
s1 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e9); }
|
||||
}
|
||||
if (s1 !== peg$FAILED) {
|
||||
s2 = [];
|
||||
s3 = peg$parseany();
|
||||
while (s3 !== peg$FAILED) {
|
||||
s2.push(s3);
|
||||
s3 = peg$parseany();
|
||||
}
|
||||
s3 = peg$currPos;
|
||||
peg$silentFails++;
|
||||
s4 = peg$parsenewLine();
|
||||
peg$silentFails--;
|
||||
if (s4 !== peg$FAILED) {
|
||||
peg$currPos = s3;
|
||||
s3 = undefined;
|
||||
} else {
|
||||
s3 = peg$FAILED;
|
||||
}
|
||||
if (s3 !== peg$FAILED) {
|
||||
peg$savedPos = s0;
|
||||
s0 = peg$f5();
|
||||
|
@ -827,6 +907,80 @@ function peg$parse(input, options) {
|
|||
peg$currPos = s0;
|
||||
s0 = peg$FAILED;
|
||||
}
|
||||
peg$silentFails--;
|
||||
if (s0 === peg$FAILED) {
|
||||
s1 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e8); }
|
||||
}
|
||||
|
||||
peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
|
||||
|
||||
return s0;
|
||||
}
|
||||
|
||||
function peg$parsedelimitedComment() {
|
||||
var s0, s1, s2, s3;
|
||||
|
||||
var key = peg$currPos * 12 + 7;
|
||||
var cached = peg$resultsCache[key];
|
||||
|
||||
if (cached) {
|
||||
peg$currPos = cached.nextPos;
|
||||
|
||||
return cached.result;
|
||||
}
|
||||
|
||||
peg$silentFails++;
|
||||
s0 = peg$currPos;
|
||||
if (input.substr(peg$currPos, 2) === peg$c6) {
|
||||
s1 = peg$c6;
|
||||
peg$currPos += 2;
|
||||
} else {
|
||||
s1 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e10); }
|
||||
}
|
||||
if (s1 !== peg$FAILED) {
|
||||
s2 = [];
|
||||
if (peg$r2.test(input.charAt(peg$currPos))) {
|
||||
s3 = input.charAt(peg$currPos);
|
||||
peg$currPos++;
|
||||
} else {
|
||||
s3 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e11); }
|
||||
}
|
||||
while (s3 !== peg$FAILED) {
|
||||
s2.push(s3);
|
||||
if (peg$r2.test(input.charAt(peg$currPos))) {
|
||||
s3 = input.charAt(peg$currPos);
|
||||
peg$currPos++;
|
||||
} else {
|
||||
s3 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e11); }
|
||||
}
|
||||
}
|
||||
if (input.substr(peg$currPos, 2) === peg$c7) {
|
||||
s3 = peg$c7;
|
||||
peg$currPos += 2;
|
||||
} else {
|
||||
s3 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e12); }
|
||||
}
|
||||
if (s3 !== peg$FAILED) {
|
||||
peg$savedPos = s0;
|
||||
s0 = peg$f6();
|
||||
} else {
|
||||
peg$currPos = s0;
|
||||
s0 = peg$FAILED;
|
||||
}
|
||||
} else {
|
||||
peg$currPos = s0;
|
||||
s0 = peg$FAILED;
|
||||
}
|
||||
peg$silentFails--;
|
||||
if (s0 === peg$FAILED) {
|
||||
s1 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e8); }
|
||||
}
|
||||
|
||||
peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
|
||||
|
||||
|
@ -836,7 +990,7 @@ function peg$parse(input, options) {
|
|||
function peg$parse_() {
|
||||
var s0, s1;
|
||||
|
||||
var key = peg$currPos * 10 + 7;
|
||||
var key = peg$currPos * 12 + 8;
|
||||
var cached = peg$resultsCache[key];
|
||||
|
||||
if (cached) {
|
||||
|
@ -851,12 +1005,12 @@ function peg$parse(input, options) {
|
|||
peg$currPos++;
|
||||
} else {
|
||||
s0 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e11); }
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e14); }
|
||||
}
|
||||
peg$silentFails--;
|
||||
if (s0 === peg$FAILED) {
|
||||
s1 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e10); }
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e13); }
|
||||
}
|
||||
|
||||
peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
|
||||
|
@ -867,7 +1021,7 @@ function peg$parse(input, options) {
|
|||
function peg$parsenewLine() {
|
||||
var s0, s1;
|
||||
|
||||
var key = peg$currPos * 10 + 8;
|
||||
var key = peg$currPos * 12 + 9;
|
||||
var cached = peg$resultsCache[key];
|
||||
|
||||
if (cached) {
|
||||
|
@ -882,12 +1036,12 @@ function peg$parse(input, options) {
|
|||
peg$currPos++;
|
||||
} else {
|
||||
s0 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e13); }
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e16); }
|
||||
}
|
||||
peg$silentFails--;
|
||||
if (s0 === peg$FAILED) {
|
||||
s1 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e12); }
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e15); }
|
||||
}
|
||||
|
||||
peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
|
||||
|
@ -896,9 +1050,9 @@ function peg$parse(input, options) {
|
|||
}
|
||||
|
||||
function peg$parseany() {
|
||||
var s0;
|
||||
var s0, s1;
|
||||
|
||||
var key = peg$currPos * 10 + 9;
|
||||
var key = peg$currPos * 12 + 10;
|
||||
var cached = peg$resultsCache[key];
|
||||
|
||||
if (cached) {
|
||||
|
@ -907,12 +1061,96 @@ function peg$parse(input, options) {
|
|||
return cached.result;
|
||||
}
|
||||
|
||||
peg$silentFails++;
|
||||
if (peg$r5.test(input.charAt(peg$currPos))) {
|
||||
s0 = input.charAt(peg$currPos);
|
||||
peg$currPos++;
|
||||
} else {
|
||||
s0 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e14); }
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e18); }
|
||||
}
|
||||
peg$silentFails--;
|
||||
if (s0 === peg$FAILED) {
|
||||
s1 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e17); }
|
||||
}
|
||||
|
||||
peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
|
||||
|
||||
return s0;
|
||||
}
|
||||
|
||||
function peg$parseidentifier() {
|
||||
var s0, s1, s2, s3, s4;
|
||||
|
||||
var key = peg$currPos * 12 + 11;
|
||||
var cached = peg$resultsCache[key];
|
||||
|
||||
if (cached) {
|
||||
peg$currPos = cached.nextPos;
|
||||
|
||||
return cached.result;
|
||||
}
|
||||
|
||||
peg$silentFails++;
|
||||
s0 = peg$currPos;
|
||||
s1 = peg$currPos;
|
||||
s2 = [];
|
||||
if (peg$r6.test(input.charAt(peg$currPos))) {
|
||||
s3 = input.charAt(peg$currPos);
|
||||
peg$currPos++;
|
||||
} else {
|
||||
s3 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e20); }
|
||||
}
|
||||
if (s3 !== peg$FAILED) {
|
||||
while (s3 !== peg$FAILED) {
|
||||
s2.push(s3);
|
||||
if (peg$r6.test(input.charAt(peg$currPos))) {
|
||||
s3 = input.charAt(peg$currPos);
|
||||
peg$currPos++;
|
||||
} else {
|
||||
s3 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e20); }
|
||||
}
|
||||
}
|
||||
} else {
|
||||
s2 = peg$FAILED;
|
||||
}
|
||||
if (s2 !== peg$FAILED) {
|
||||
s3 = [];
|
||||
if (peg$r7.test(input.charAt(peg$currPos))) {
|
||||
s4 = input.charAt(peg$currPos);
|
||||
peg$currPos++;
|
||||
} else {
|
||||
s4 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e21); }
|
||||
}
|
||||
while (s4 !== peg$FAILED) {
|
||||
s3.push(s4);
|
||||
if (peg$r7.test(input.charAt(peg$currPos))) {
|
||||
s4 = input.charAt(peg$currPos);
|
||||
peg$currPos++;
|
||||
} else {
|
||||
s4 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e21); }
|
||||
}
|
||||
}
|
||||
s2 = [s2, s3];
|
||||
s1 = s2;
|
||||
} else {
|
||||
peg$currPos = s1;
|
||||
s1 = peg$FAILED;
|
||||
}
|
||||
if (s1 !== peg$FAILED) {
|
||||
peg$savedPos = s0;
|
||||
s1 = peg$f7();
|
||||
}
|
||||
s0 = s1;
|
||||
peg$silentFails--;
|
||||
if (s0 === peg$FAILED) {
|
||||
s1 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e19); }
|
||||
}
|
||||
|
||||
peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
|
||||
|
|
|
@ -1,33 +1,37 @@
|
|||
// Includes are at the start of the file, before any other code.
|
||||
// There might be some comments before or between the includes.
|
||||
// #include "string"
|
||||
// #include "string2"
|
||||
// #include "string2" as aVariable
|
||||
|
||||
start
|
||||
= (newLine/_/comment/delimitedComment)* @includes newLine* ignore
|
||||
|
||||
includes
|
||||
= head:includeStatement tail:(newLine+ @includeStatement)*
|
||||
= head:dependencyStatement tail:(newLine+ @dependencyStatement)*
|
||||
{return [head, ...tail].filter( e => e != '');}
|
||||
/ ignore
|
||||
/ ! '#'
|
||||
{return [];}
|
||||
|
||||
includeStatement
|
||||
= _* '#include' _* @string _*
|
||||
dependencyStatement
|
||||
= includeStatement
|
||||
/ comment
|
||||
/ delimitedComment
|
||||
|
||||
includeStatement
|
||||
= _* '#include' _+ file:string variable:(_+ 'as' _+ @identifier)? _* & newLine
|
||||
{return [!variable ? '' : variable, file]}
|
||||
|
||||
string 'string'
|
||||
= characters:("'" @([^'])* "'") {return characters.join('');}
|
||||
/ characters:('"' @([^"])* '"') {return characters.join('');}
|
||||
|
||||
ignore = (any / newLine / _)*
|
||||
|
||||
comment
|
||||
= '//'any*
|
||||
comment 'comment'
|
||||
= '//'any* & newLine
|
||||
{ return '';}
|
||||
|
||||
delimitedComment
|
||||
delimitedComment 'comment'
|
||||
= '/*' ([^*]*) '*/'
|
||||
{ return '';}
|
||||
|
||||
|
@ -37,4 +41,8 @@ _ "white space"
|
|||
newLine "newline"
|
||||
= [\n\r]
|
||||
|
||||
any = [^\r\n]
|
||||
any 'code'
|
||||
= [^\r\n]
|
||||
|
||||
identifier 'identifier'
|
||||
= ([_a-z]+[_a-z0-9]i*) {return text();}
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
@module("./ReducerProject_IncludeParser.js") external parse__: string => array<string> = "parse"
|
||||
@module("./ReducerProject_IncludeParser.js")
|
||||
external parse__: string => array<array<string>> = "parse"
|
||||
|
||||
let parseIncludes = (expr: string): result<array<string>, Reducer_ErrorValue.errorValue> =>
|
||||
let parseIncludes = (expr: string): result<
|
||||
array<(string, string)>,
|
||||
Reducer_ErrorValue.errorValue,
|
||||
> =>
|
||||
try {
|
||||
let answer = parse__(expr)
|
||||
// let logEntry = answer->Js.Array2.joinWith(",")
|
||||
// `parseIncludes: ${logEntry} for expr: ${expr}`->Js.log
|
||||
answer->Ok
|
||||
Belt.Array.map(answer, item => (item[0], item[1]))->Ok
|
||||
} catch {
|
||||
| Js.Exn.Error(obj) =>
|
||||
RESyntaxError(
|
||||
|
|
|
@ -19,6 +19,8 @@ let emptyItem = T.ProjectItem({
|
|||
result: None,
|
||||
continues: [],
|
||||
includes: []->Ok,
|
||||
directIncludes: [],
|
||||
includeAsVariables: [],
|
||||
})
|
||||
// source -> rawParse -> includes -> expression -> continuation -> result
|
||||
|
||||
|
@ -30,40 +32,59 @@ let getResult = (T.ProjectItem(r)): T.resultType => r.result
|
|||
|
||||
let getContinues = (T.ProjectItem(r)): T.continuesType => r.continues
|
||||
let getIncludes = (T.ProjectItem(r)): T.includesType => r.includes
|
||||
let getDirectIncludes = (T.ProjectItem(r)): array<string> => r.directIncludes
|
||||
let getIncludesAsVariables = (T.ProjectItem(r)): T.importAsVariablesType => r.includeAsVariables
|
||||
|
||||
let touchSource = (this: t): t => {
|
||||
let T.ProjectItem(r) = emptyItem
|
||||
T.ProjectItem({
|
||||
...r,
|
||||
includes: getIncludes(this),
|
||||
continues: getContinues(this),
|
||||
source: getSource(this),
|
||||
continues: getContinues(this),
|
||||
includes: getIncludes(this),
|
||||
includeAsVariables: getIncludesAsVariables(this),
|
||||
directIncludes: getDirectIncludes(this),
|
||||
})
|
||||
}
|
||||
|
||||
let touchRawParse = (this: t): t => {
|
||||
let T.ProjectItem(r) = emptyItem
|
||||
T.ProjectItem({
|
||||
...r,
|
||||
continues: getContinues(this),
|
||||
source: getSource(this),
|
||||
rawParse: getRawParse(this),
|
||||
continues: getContinues(this),
|
||||
includes: getIncludes(this),
|
||||
includeAsVariables: getIncludesAsVariables(this),
|
||||
directIncludes: getDirectIncludes(this),
|
||||
rawParse: getRawParse(this),
|
||||
})
|
||||
}
|
||||
|
||||
let touchExpression = (this: t): t => {
|
||||
let T.ProjectItem(r) = emptyItem
|
||||
T.ProjectItem({
|
||||
...r,
|
||||
continues: getContinues(this),
|
||||
source: getSource(this),
|
||||
rawParse: getRawParse(this),
|
||||
continues: getContinues(this),
|
||||
includes: getIncludes(this),
|
||||
includeAsVariables: getIncludesAsVariables(this),
|
||||
directIncludes: getDirectIncludes(this),
|
||||
rawParse: getRawParse(this),
|
||||
expression: getExpression(this),
|
||||
})
|
||||
}
|
||||
|
||||
let resetIncludes = (T.ProjectItem(r): t): t => {
|
||||
T.ProjectItem({
|
||||
...r,
|
||||
includes: []->Ok,
|
||||
includeAsVariables: [],
|
||||
directIncludes: [],
|
||||
})
|
||||
}
|
||||
|
||||
let setSource = (T.ProjectItem(r): t, source: T.sourceArgumentType): t =>
|
||||
T.ProjectItem({...r, source: source})->touchSource
|
||||
T.ProjectItem({...r, source: source})->resetIncludes->touchSource
|
||||
|
||||
let setRawParse = (T.ProjectItem(r): t, rawParse: T.rawParseArgumentType): t =>
|
||||
T.ProjectItem({...r, rawParse: Some(rawParse)})->touchRawParse
|
||||
|
@ -95,6 +116,10 @@ let clean = (this: t): t => {
|
|||
let getImmediateDependencies = (this: t): T.includesType =>
|
||||
getIncludes(this)->Belt.Result.map(Js.Array2.concat(_, getContinues(this)))
|
||||
|
||||
let getPastChain = (this: t): array<string> => {
|
||||
Js.Array2.concat(getDirectIncludes(this), getContinues(this))
|
||||
}
|
||||
|
||||
let setContinues = (T.ProjectItem(r): t, continues: array<string>): t =>
|
||||
T.ProjectItem({...r, continues: continues})->touchSource
|
||||
let removeContinues = (T.ProjectItem(r): t): t => T.ProjectItem({...r, continues: []})->touchSource
|
||||
|
@ -104,10 +129,38 @@ let setIncludes = (T.ProjectItem(r): t, includes: T.includesType): t => T.Projec
|
|||
includes: includes,
|
||||
})
|
||||
|
||||
//TODO: forward parse errors to the user
|
||||
let parseIncludes = (this: t): t =>
|
||||
setIncludes(this, getSource(this)->ReducerProject_ParseIncludes.parseIncludes)
|
||||
let setImportAsVariables = (
|
||||
T.ProjectItem(r): t,
|
||||
includeAsVariables: T.importAsVariablesType,
|
||||
): t => T.ProjectItem({...r, includeAsVariables: includeAsVariables})
|
||||
|
||||
let setDirectImports = (T.ProjectItem(r): t, directIncludes: array<string>): t => T.ProjectItem({
|
||||
...r,
|
||||
directIncludes: directIncludes,
|
||||
})
|
||||
|
||||
let parseIncludes = (this: t): t => {
|
||||
let T.ProjectItem(r) = this
|
||||
let rRawImportAsVariables = getSource(this)->ReducerProject_ParseIncludes.parseIncludes
|
||||
switch rRawImportAsVariables {
|
||||
| Error(e) => resetIncludes(this)->setIncludes(Error(e))
|
||||
| Ok(rawImportAsVariables) => {
|
||||
let includes = rawImportAsVariables->Belt.Array.map(((_variable, file)) => file)->Ok
|
||||
let includeAsVariables =
|
||||
rawImportAsVariables->Belt.Array.keep(((variable, _file)) => variable != "")
|
||||
let directIncludes =
|
||||
rawImportAsVariables
|
||||
->Belt.Array.keep(((variable, _file)) => variable == "")
|
||||
->Belt.Array.map(((_variable, file)) => file)
|
||||
T.ProjectItem({
|
||||
...r,
|
||||
includes: includes,
|
||||
includeAsVariables: includeAsVariables,
|
||||
directIncludes: directIncludes,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
let doRawParse = (this: t): T.rawParseArgumentType => this->getSource->Reducer_Peggy_Parse.parse
|
||||
|
||||
let rawParse = (this: t): t =>
|
||||
|
|
|
@ -21,6 +21,7 @@ type continuesArgumentType = array<string>
|
|||
type continuesType = array<string>
|
||||
type includesArgumentType = string
|
||||
type includesType = result<array<string>, errorValue>
|
||||
type importAsVariablesType = array<(string, string)>
|
||||
|
||||
type projectItem =
|
||||
| ProjectItem({
|
||||
|
@ -30,7 +31,9 @@ type projectItem =
|
|||
continuation: continuationArgumentType,
|
||||
result: resultType,
|
||||
continues: continuesType,
|
||||
includes: includesType,
|
||||
})
|
||||
includes: includesType, //For loader
|
||||
includeAsVariables: importAsVariablesType, //For linker
|
||||
directIncludes: array<string>,
|
||||
}) //For linker
|
||||
|
||||
type t = projectItem
|
||||
|
|
|
@ -19,4 +19,4 @@ let mathBindings: Bindings.t =
|
|||
->Bindings.fromArray
|
||||
|
||||
let makeBindings = (previousBindings: Bindings.t): Bindings.t =>
|
||||
previousBindings->Bindings.merge(mathBindings)
|
||||
previousBindings->Bindings.mergeFrom(mathBindings)
|
||||
|
|
|
@ -6,4 +6,4 @@ let bindings: Bindings.t =
|
|||
]->Bindings.fromArray
|
||||
|
||||
let makeBindings = (previousBindings: Bindings.t): Bindings.t =>
|
||||
previousBindings->Bindings.merge(bindings)
|
||||
previousBindings->Bindings.mergeFrom(bindings)
|
||||
|
|
Loading…
Reference in New Issue
Block a user