still WIP, FR works
This commit is contained in:
		
							parent
							
								
									7a29be3845
								
							
						
					
					
						commit
						f2dccd4f1e
					
				| 
						 | 
					@ -135,23 +135,23 @@ export const ExpressionViewer: React.FC<Props> = ({ value, width }) => {
 | 
				
			||||||
          {() => value.value.toString()}
 | 
					          {() => value.value.toString()}
 | 
				
			||||||
        </VariableBox>
 | 
					        </VariableBox>
 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
    case SqValueTag.Symbol:
 | 
					    // case SqValueTag.Symbol:
 | 
				
			||||||
      return (
 | 
					    //   return (
 | 
				
			||||||
        <VariableBox value={value} heading="Symbol">
 | 
					    //     <VariableBox value={value} heading="Symbol">
 | 
				
			||||||
          {() => (
 | 
					    //       {() => (
 | 
				
			||||||
            <>
 | 
					    //         <>
 | 
				
			||||||
              <span className="text-slate-500 mr-2">Undefined Symbol:</span>
 | 
					    //           <span className="text-slate-500 mr-2">Undefined Symbol:</span>
 | 
				
			||||||
              <span className="text-slate-600">{value.value}</span>
 | 
					    //           <span className="text-slate-600">{value.value}</span>
 | 
				
			||||||
            </>
 | 
					    //         </>
 | 
				
			||||||
          )}
 | 
					    //       )}
 | 
				
			||||||
        </VariableBox>
 | 
					    //     </VariableBox>
 | 
				
			||||||
      );
 | 
					    //   );
 | 
				
			||||||
    case SqValueTag.Call:
 | 
					    // case SqValueTag.Call:
 | 
				
			||||||
      return (
 | 
					    //   return (
 | 
				
			||||||
        <VariableBox value={value} heading="Call">
 | 
					    //     <VariableBox value={value} heading="Call">
 | 
				
			||||||
          {() => value.value}
 | 
					    //       {() => value.value}
 | 
				
			||||||
        </VariableBox>
 | 
					    //     </VariableBox>
 | 
				
			||||||
      );
 | 
					    //   );
 | 
				
			||||||
    case SqValueTag.ArrayString:
 | 
					    case SqValueTag.ArrayString:
 | 
				
			||||||
      return (
 | 
					      return (
 | 
				
			||||||
        <VariableBox value={value} heading="Array String">
 | 
					        <VariableBox value={value} heading="Array String">
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,7 +14,7 @@ let rec evaluate: T.reducerFn = (
 | 
				
			||||||
  expression,
 | 
					  expression,
 | 
				
			||||||
  context
 | 
					  context
 | 
				
			||||||
) => {
 | 
					) => {
 | 
				
			||||||
  Js.log(`reduce: ${expression->Reducer_Expression_T.toString}`)
 | 
					  // Js.log(`reduce: ${expression->Reducer_Expression_T.toString}`)
 | 
				
			||||||
  switch expression {
 | 
					  switch expression {
 | 
				
			||||||
    | T.EBlock(statements) => {
 | 
					    | T.EBlock(statements) => {
 | 
				
			||||||
      let innerContext = {...context, bindings: context.bindings->Bindings.extend}
 | 
					      let innerContext = {...context, bindings: context.bindings->Bindings.extend}
 | 
				
			||||||
| 
						 | 
					@ -25,12 +25,12 @@ let rec evaluate: T.reducerFn = (
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    | T.EProgram(statements) => {
 | 
					    | T.EProgram(statements) => {
 | 
				
			||||||
      Js.log(`bindings: ${context.bindings->Reducer_Bindings.toString}`)
 | 
					      // Js.log(`bindings: ${context.bindings->Reducer_Bindings.toString}`)
 | 
				
			||||||
      let res = statements->Js.Array2.reduce(
 | 
					      let res = statements->Js.Array2.reduce(
 | 
				
			||||||
        (acc, statement) => statement->evaluate(context),
 | 
					        (acc, statement) => statement->evaluate(context),
 | 
				
			||||||
        T.IEvVoid
 | 
					        T.IEvVoid
 | 
				
			||||||
      )
 | 
					      )
 | 
				
			||||||
      Js.log(`bindings after: ${context.bindings->Reducer_Bindings.toString}`)
 | 
					      // Js.log(`bindings after: ${context.bindings->Reducer_Bindings.toString}`)
 | 
				
			||||||
      res
 | 
					      res
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -43,11 +43,14 @@ let makeLambda = (
 | 
				
			||||||
    reducer(body, { bindings: localBindings, environment })
 | 
					    reducer(body, { bindings: localBindings, environment })
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  LNoFFI({
 | 
					  {
 | 
				
			||||||
    context: bindings,
 | 
					    // context: bindings,
 | 
				
			||||||
    body: lambda,
 | 
					    body: lambda,
 | 
				
			||||||
    parameters,
 | 
					    parameters,
 | 
				
			||||||
  })
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let makeFFILambda = () => raise(Not_found)
 | 
					let makeFFILambda = (body: Reducer_T.lambdaBody): Reducer_T.lambdaValue => {
 | 
				
			||||||
 | 
					  body,
 | 
				
			||||||
 | 
					  parameters: ["..."]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,23 +13,8 @@ outerBlock
 | 
				
			||||||
  = statements:array_statements  finalExpression: (statementSeparator @expression)?
 | 
					  = statements:array_statements  finalExpression: (statementSeparator @expression)?
 | 
				
			||||||
    { if (finalExpression) statements.push(finalExpression) 
 | 
					    { if (finalExpression) statements.push(finalExpression) 
 | 
				
			||||||
      return h.nodeProgram(statements) }
 | 
					      return h.nodeProgram(statements) }
 | 
				
			||||||
  // / '{' _nl finalExpression: expression  _nl '}'
 | 
					  / finalExpression: expression
 | 
				
			||||||
  //     { return h.nodeBlock([finalExpression]) }
 | 
					    { return h.nodeProgram([finalExpression]) }
 | 
				
			||||||
  //   { if (finalExpression != null) 
 | 
					 | 
				
			||||||
  //       { 
 | 
					 | 
				
			||||||
  //         var newFinalExpression = h.makeFunctionCall('$_endOfOuterBlock_$', [h.nodeVoid(), finalExpression]);
 | 
					 | 
				
			||||||
  //         statements.push(newFinalExpression);
 | 
					 | 
				
			||||||
  //       }
 | 
					 | 
				
			||||||
  //     else 
 | 
					 | 
				
			||||||
  //       {
 | 
					 | 
				
			||||||
  //         var newFinalStatement = h.makeFunctionCall('$_endOfOuterBlock_$', [h.nodeVoid(), h.nodeVoid()]);
 | 
					 | 
				
			||||||
  //         statements.push(newFinalStatement);
 | 
					 | 
				
			||||||
  //       }
 | 
					 | 
				
			||||||
  //     return h.nodeBlock(statements) }
 | 
					 | 
				
			||||||
  // / finalExpression: expression
 | 
					 | 
				
			||||||
  //   { 
 | 
					 | 
				
			||||||
  //     var newFinalExpression = h.makeFunctionCall('$_endOfOuterBlock_$', [h.nodeVoid(), finalExpression]);
 | 
					 | 
				
			||||||
  //     return h.nodeBlock([newFinalExpression])}
 | 
					 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
innerBlockOrExpression  
 | 
					innerBlockOrExpression  
 | 
				
			||||||
  = quotedInnerBlock
 | 
					  = quotedInnerBlock
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,16 +22,13 @@ type rec value =
 | 
				
			||||||
@genType.opaque and arrayValue = array<value>
 | 
					@genType.opaque and arrayValue = array<value>
 | 
				
			||||||
@genType.opaque and map = Belt.Map.String.t<value>
 | 
					@genType.opaque and map = Belt.Map.String.t<value>
 | 
				
			||||||
@genType.opaque and nameSpace = NameSpace(Belt.MutableMap.String.t<value>, option<nameSpace>)
 | 
					@genType.opaque and nameSpace = NameSpace(Belt.MutableMap.String.t<value>, option<nameSpace>)
 | 
				
			||||||
 | 
					and lambdaBody = (array<value>, environment, reducerFn) => value
 | 
				
			||||||
@genType.opaque
 | 
					@genType.opaque
 | 
				
			||||||
and lambdaValue =
 | 
					and lambdaValue = {
 | 
				
			||||||
  | LNoFFI({
 | 
					 | 
				
			||||||
    parameters: array<string>,
 | 
					    parameters: array<string>,
 | 
				
			||||||
    context: nameSpace,
 | 
					    // context: nameSpace,
 | 
				
			||||||
    body: (array<value>, environment, reducerFn) => value,
 | 
					    body: (array<value>, environment, reducerFn) => value,
 | 
				
			||||||
  })
 | 
					  }
 | 
				
			||||||
  | LFFI({
 | 
					 | 
				
			||||||
    body: (array<value>, environment, reducerFn) => value,
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
@genType.opaque and lambdaDeclaration = Declaration.declaration<lambdaValue>
 | 
					@genType.opaque and lambdaDeclaration = Declaration.declaration<lambdaValue>
 | 
				
			||||||
and expression =
 | 
					and expression =
 | 
				
			||||||
  | EBlock(array<expression>)
 | 
					  | EBlock(array<expression>)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -49,10 +49,7 @@ and toStringDate = date => DateTime.Date.toString(date)
 | 
				
			||||||
and toStringDeclaration = d => Declaration.toString(d, r => toString(IEvLambda(r)))
 | 
					and toStringDeclaration = d => Declaration.toString(d, r => toString(IEvLambda(r)))
 | 
				
			||||||
and toStringDistribution = dist => GenericDist.toString(dist)
 | 
					and toStringDistribution = dist => GenericDist.toString(dist)
 | 
				
			||||||
and toStringLambda = (lambdaValue: T.lambdaValue) =>
 | 
					and toStringLambda = (lambdaValue: T.lambdaValue) =>
 | 
				
			||||||
  switch lambdaValue {
 | 
					  `lambda(${Js.Array2.toString(lambdaValue.parameters)}=>internal code)`
 | 
				
			||||||
    | LNoFFI({ parameters }) => `lambda(${parameters->Js.Array2.toString}=>internal code)` // TODO - serialize code too?
 | 
					 | 
				
			||||||
    | LFFI(_) => `standard function` // TODO - serialize name, etc?
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
and toStringFunction = (lambdaValue: T.lambdaValue) => `function(${Js.Array2.toString(lambdaValue.parameters)})`
 | 
					and toStringFunction = (lambdaValue: T.lambdaValue) => `function(${Js.Array2.toString(lambdaValue.parameters)})`
 | 
				
			||||||
and toStringNumber = aNumber => Js.String.make(aNumber)
 | 
					and toStringNumber = aNumber => Js.String.make(aNumber)
 | 
				
			||||||
and toStringRecord = aMap => aMap->toStringMap
 | 
					and toStringRecord = aMap => aMap->toStringMap
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,34 @@
 | 
				
			||||||
let internalStdLib: Reducer_Bindings.t =
 | 
					let internalStdLib: Reducer_Bindings.t = {
 | 
				
			||||||
  Reducer_Bindings.makeEmptyBindings()
 | 
					  let res = Reducer_Bindings.makeEmptyBindings()
 | 
				
			||||||
  ->SquiggleLibrary_Math.makeBindings
 | 
					  ->SquiggleLibrary_Math.makeBindings
 | 
				
			||||||
  ->SquiggleLibrary_Versions.makeBindings
 | 
					  ->SquiggleLibrary_Versions.makeBindings
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let _ = res->Reducer_Bindings.set("multiply", Reducer_Expression_Lambda.makeFFILambda(
 | 
				
			||||||
 | 
					    (arguments, _, _) => {
 | 
				
			||||||
 | 
					      switch arguments {
 | 
				
			||||||
 | 
					        | [IEvNumber(x), IEvNumber(y)] => IEvNumber(x *. y)
 | 
				
			||||||
 | 
					        | _ => raise(Not_found)
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  )->Reducer_T.IEvLambda)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  FunctionRegistry_Library.registry.fnNameDict->Js.Dict.keys->Js.Array2.forEach(
 | 
				
			||||||
 | 
					    (name) => {
 | 
				
			||||||
 | 
					      let _ = res->Reducer_Bindings.set(name, Reducer_Expression_Lambda.makeFFILambda(
 | 
				
			||||||
 | 
					        (arguments, environment, reducer) => {
 | 
				
			||||||
 | 
					          switch FunctionRegistry_Library.dispatch((name, arguments), environment, reducer) {
 | 
				
			||||||
 | 
					            | Some(result) => {
 | 
				
			||||||
 | 
					              switch result {
 | 
				
			||||||
 | 
					                | Ok(value) => value
 | 
				
			||||||
 | 
					                | Error(error) => error->Reducer_ErrorValue.ErrorException->raise
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            | None => Reducer_ErrorValue.RESymbolNotFound("Not found in registry")->Reducer_ErrorValue.ErrorException->raise
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      )->Reducer_T.IEvLambda)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  res
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -193,7 +193,7 @@ let doLinkAndRun = (project: t, sourceId: string): unit => {
 | 
				
			||||||
  // FIXME: fill context with dependencies
 | 
					  // FIXME: fill context with dependencies
 | 
				
			||||||
  // let continuation = linkDependencies(project, sourceId)
 | 
					  // let continuation = linkDependencies(project, sourceId)
 | 
				
			||||||
  let newItem = project->getItem(sourceId)->ProjectItem.run(context)
 | 
					  let newItem = project->getItem(sourceId)->ProjectItem.run(context)
 | 
				
			||||||
  Js.log("after run " ++ newItem.continuation->Reducer_Bindings.toString)
 | 
					  // Js.log("after run " ++ newItem.continuation->Reducer_Bindings.toString)
 | 
				
			||||||
  project->setItem(sourceId, newItem)
 | 
					  project->setItem(sourceId, newItem)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,9 +1,9 @@
 | 
				
			||||||
@module("./MathjsWrapper.js")
 | 
					// @module("./MathjsWrapper.js")
 | 
				
			||||||
external parseMathExt: string => Js.Json.t = "parseMath"
 | 
					// external parseMathExt: string => Js.Json.t = "parseMath"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let parseMath = (str: string): result<Js.Json.t, string> =>
 | 
					// let parseMath = (str: string): result<Js.Json.t, string> =>
 | 
				
			||||||
  switch parseMathExt(str) {
 | 
					//   switch parseMathExt(str) {
 | 
				
			||||||
  | exception Js.Exn.Error(err) => Error(Js.Exn.message(err) |> E.O.default("MathJS Parse Error"))
 | 
					//   | exception Js.Exn.Error(err) => Error(Js.Exn.message(err) |> E.O.default("MathJS Parse Error"))
 | 
				
			||||||
  | exception _ => Error("MathJS Parse Error")
 | 
					//   | exception _ => Error("MathJS Parse Error")
 | 
				
			||||||
  | j => Ok(j)
 | 
					//   | j => Ok(j)
 | 
				
			||||||
  }
 | 
					//   }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user