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()}
 | 
			
		||||
        </VariableBox>
 | 
			
		||||
      );
 | 
			
		||||
    case SqValueTag.Symbol:
 | 
			
		||||
      return (
 | 
			
		||||
        <VariableBox value={value} heading="Symbol">
 | 
			
		||||
          {() => (
 | 
			
		||||
            <>
 | 
			
		||||
              <span className="text-slate-500 mr-2">Undefined Symbol:</span>
 | 
			
		||||
              <span className="text-slate-600">{value.value}</span>
 | 
			
		||||
            </>
 | 
			
		||||
          )}
 | 
			
		||||
        </VariableBox>
 | 
			
		||||
      );
 | 
			
		||||
    case SqValueTag.Call:
 | 
			
		||||
      return (
 | 
			
		||||
        <VariableBox value={value} heading="Call">
 | 
			
		||||
          {() => value.value}
 | 
			
		||||
        </VariableBox>
 | 
			
		||||
      );
 | 
			
		||||
    // case SqValueTag.Symbol:
 | 
			
		||||
    //   return (
 | 
			
		||||
    //     <VariableBox value={value} heading="Symbol">
 | 
			
		||||
    //       {() => (
 | 
			
		||||
    //         <>
 | 
			
		||||
    //           <span className="text-slate-500 mr-2">Undefined Symbol:</span>
 | 
			
		||||
    //           <span className="text-slate-600">{value.value}</span>
 | 
			
		||||
    //         </>
 | 
			
		||||
    //       )}
 | 
			
		||||
    //     </VariableBox>
 | 
			
		||||
    //   );
 | 
			
		||||
    // case SqValueTag.Call:
 | 
			
		||||
    //   return (
 | 
			
		||||
    //     <VariableBox value={value} heading="Call">
 | 
			
		||||
    //       {() => value.value}
 | 
			
		||||
    //     </VariableBox>
 | 
			
		||||
    //   );
 | 
			
		||||
    case SqValueTag.ArrayString:
 | 
			
		||||
      return (
 | 
			
		||||
        <VariableBox value={value} heading="Array String">
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,7 +14,7 @@ let rec evaluate: T.reducerFn = (
 | 
			
		|||
  expression,
 | 
			
		||||
  context
 | 
			
		||||
) => {
 | 
			
		||||
  Js.log(`reduce: ${expression->Reducer_Expression_T.toString}`)
 | 
			
		||||
  // Js.log(`reduce: ${expression->Reducer_Expression_T.toString}`)
 | 
			
		||||
  switch expression {
 | 
			
		||||
    | T.EBlock(statements) => {
 | 
			
		||||
      let innerContext = {...context, bindings: context.bindings->Bindings.extend}
 | 
			
		||||
| 
						 | 
				
			
			@ -25,12 +25,12 @@ let rec evaluate: T.reducerFn = (
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    | 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(
 | 
			
		||||
        (acc, statement) => statement->evaluate(context),
 | 
			
		||||
        T.IEvVoid
 | 
			
		||||
      )
 | 
			
		||||
      Js.log(`bindings after: ${context.bindings->Reducer_Bindings.toString}`)
 | 
			
		||||
      // Js.log(`bindings after: ${context.bindings->Reducer_Bindings.toString}`)
 | 
			
		||||
      res
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -43,11 +43,14 @@ let makeLambda = (
 | 
			
		|||
    reducer(body, { bindings: localBindings, environment })
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  LNoFFI({
 | 
			
		||||
    context: bindings,
 | 
			
		||||
  {
 | 
			
		||||
    // context: bindings,
 | 
			
		||||
    body: lambda,
 | 
			
		||||
    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)?
 | 
			
		||||
    { if (finalExpression) statements.push(finalExpression) 
 | 
			
		||||
      return h.nodeProgram(statements) }
 | 
			
		||||
  // / '{' _nl finalExpression: expression  _nl '}'
 | 
			
		||||
  //     { return h.nodeBlock([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])}
 | 
			
		||||
  / finalExpression: expression
 | 
			
		||||
    { return h.nodeProgram([finalExpression]) }
 | 
			
		||||
    
 | 
			
		||||
innerBlockOrExpression  
 | 
			
		||||
  = quotedInnerBlock
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,16 +22,13 @@ type rec value =
 | 
			
		|||
@genType.opaque and arrayValue = array<value>
 | 
			
		||||
@genType.opaque and map = Belt.Map.String.t<value>
 | 
			
		||||
@genType.opaque and nameSpace = NameSpace(Belt.MutableMap.String.t<value>, option<nameSpace>)
 | 
			
		||||
and lambdaBody = (array<value>, environment, reducerFn) => value
 | 
			
		||||
@genType.opaque
 | 
			
		||||
and lambdaValue =
 | 
			
		||||
  | LNoFFI({
 | 
			
		||||
and lambdaValue = {
 | 
			
		||||
    parameters: array<string>,
 | 
			
		||||
    context: nameSpace,
 | 
			
		||||
    // context: nameSpace,
 | 
			
		||||
    body: (array<value>, environment, reducerFn) => value,
 | 
			
		||||
  })
 | 
			
		||||
  | LFFI({
 | 
			
		||||
    body: (array<value>, environment, reducerFn) => value,
 | 
			
		||||
  })
 | 
			
		||||
  }
 | 
			
		||||
@genType.opaque and lambdaDeclaration = Declaration.declaration<lambdaValue>
 | 
			
		||||
and 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 toStringDistribution = dist => GenericDist.toString(dist)
 | 
			
		||||
and toStringLambda = (lambdaValue: T.lambdaValue) =>
 | 
			
		||||
  switch lambdaValue {
 | 
			
		||||
    | LNoFFI({ parameters }) => `lambda(${parameters->Js.Array2.toString}=>internal code)` // TODO - serialize code too?
 | 
			
		||||
    | LFFI(_) => `standard function` // TODO - serialize name, etc?
 | 
			
		||||
  }
 | 
			
		||||
  `lambda(${Js.Array2.toString(lambdaValue.parameters)}=>internal code)`
 | 
			
		||||
and toStringFunction = (lambdaValue: T.lambdaValue) => `function(${Js.Array2.toString(lambdaValue.parameters)})`
 | 
			
		||||
and toStringNumber = aNumber => Js.String.make(aNumber)
 | 
			
		||||
and toStringRecord = aMap => aMap->toStringMap
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,34 @@
 | 
			
		|||
let internalStdLib: Reducer_Bindings.t =
 | 
			
		||||
  Reducer_Bindings.makeEmptyBindings()
 | 
			
		||||
let internalStdLib: Reducer_Bindings.t = {
 | 
			
		||||
  let res = Reducer_Bindings.makeEmptyBindings()
 | 
			
		||||
  ->SquiggleLibrary_Math.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
 | 
			
		||||
  // let continuation = linkDependencies(project, sourceId)
 | 
			
		||||
  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)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,9 +1,9 @@
 | 
			
		|||
@module("./MathjsWrapper.js")
 | 
			
		||||
external parseMathExt: string => Js.Json.t = "parseMath"
 | 
			
		||||
// @module("./MathjsWrapper.js")
 | 
			
		||||
// external parseMathExt: string => Js.Json.t = "parseMath"
 | 
			
		||||
 | 
			
		||||
let parseMath = (str: string): result<Js.Json.t, string> =>
 | 
			
		||||
  switch parseMathExt(str) {
 | 
			
		||||
  | exception Js.Exn.Error(err) => Error(Js.Exn.message(err) |> E.O.default("MathJS Parse Error"))
 | 
			
		||||
  | exception _ => Error("MathJS Parse Error")
 | 
			
		||||
  | j => Ok(j)
 | 
			
		||||
  }
 | 
			
		||||
// let parseMath = (str: string): result<Js.Json.t, string> =>
 | 
			
		||||
//   switch parseMathExt(str) {
 | 
			
		||||
//   | exception Js.Exn.Error(err) => Error(Js.Exn.message(err) |> E.O.default("MathJS Parse Error"))
 | 
			
		||||
//   | exception _ => Error("MathJS Parse Error")
 | 
			
		||||
//   | j => Ok(j)
 | 
			
		||||
//   }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user