feat: __functor
This commit is contained in:
@@ -3,10 +3,11 @@
|
||||
*/
|
||||
|
||||
import type { NixValue, NixAttrs, NixBool, NixString } from "./types";
|
||||
import { forceAttrs, forceString } from "./type-assert";
|
||||
import { forceAttrs, forceFunction, forceString, typeName } from "./type-assert";
|
||||
import { isAttrs } from "./builtins/type-check";
|
||||
import { coerceToString, StringCoercionMode } from "./builtins/conversion";
|
||||
import { type NixStringContext, mkStringWithContext } from "./string-context";
|
||||
import { force } from "./thunk";
|
||||
|
||||
/**
|
||||
* Concatenate multiple values into a string with context
|
||||
@@ -144,3 +145,20 @@ export const validateParams = (
|
||||
|
||||
return forced_arg;
|
||||
};
|
||||
|
||||
export const call = (func: NixValue, arg: NixValue): NixValue => {
|
||||
const forcedFunc = force(func);
|
||||
if (typeof forcedFunc === "function") {
|
||||
return forcedFunc(arg);
|
||||
}
|
||||
if (
|
||||
typeof forcedFunc === "object" &&
|
||||
!Array.isArray(forcedFunc) &&
|
||||
forcedFunc !== null &&
|
||||
"__functor" in forcedFunc
|
||||
) {
|
||||
const functor = forceFunction(forcedFunc.__functor);
|
||||
return forceFunction(functor(forcedFunc))(arg);
|
||||
}
|
||||
throw new Error(`attempt to call something which is not a function but ${typeName(forcedFunc)}`);
|
||||
};
|
||||
|
||||
@@ -5,7 +5,15 @@
|
||||
*/
|
||||
|
||||
import { createThunk, force, isThunk, IS_THUNK } from "./thunk";
|
||||
import { select, selectWithDefault, validateParams, resolvePath, hasAttr, concatStringsWithContext } from "./helpers";
|
||||
import {
|
||||
select,
|
||||
selectWithDefault,
|
||||
validateParams,
|
||||
resolvePath,
|
||||
hasAttr,
|
||||
concatStringsWithContext,
|
||||
call,
|
||||
} from "./helpers";
|
||||
import { op } from "./operators";
|
||||
import { builtins, PRIMOP_METADATA } from "./builtins";
|
||||
import { coerceToString, StringCoercionMode } from "./builtins/conversion";
|
||||
@@ -23,6 +31,7 @@ export const Nix = {
|
||||
IS_THUNK,
|
||||
HAS_CONTEXT,
|
||||
|
||||
call,
|
||||
hasAttr,
|
||||
select,
|
||||
selectWithDefault,
|
||||
|
||||
@@ -3,12 +3,21 @@
|
||||
* These functions force evaluation and verify the type, throwing errors on mismatch
|
||||
*/
|
||||
|
||||
import type { NixValue, NixList, NixAttrs, NixFunction, NixInt, NixFloat, NixNumber, NixString } from "./types";
|
||||
import type {
|
||||
NixValue,
|
||||
NixList,
|
||||
NixAttrs,
|
||||
NixFunction,
|
||||
NixInt,
|
||||
NixFloat,
|
||||
NixNumber,
|
||||
NixString,
|
||||
} from "./types";
|
||||
import { isStringWithContext } from "./types";
|
||||
import { force } from "./thunk";
|
||||
import { getStringValue } from "./string-context";
|
||||
|
||||
const typeName = (value: NixValue): string => {
|
||||
export const typeName = (value: NixValue): string => {
|
||||
const val = force(value);
|
||||
|
||||
if (typeof val === "bigint") return "int";
|
||||
|
||||
@@ -49,17 +49,13 @@ impl<Ctx: CodegenContext> Compile<Ctx> for Ir {
|
||||
Ir::Func(x) => x.compile(ctx),
|
||||
Ir::AttrSet(x) => x.compile(ctx),
|
||||
Ir::List(x) => x.compile(ctx),
|
||||
&Ir::Call(Call { func, arg }) => {
|
||||
let func = ctx.get_ir(func).compile(ctx);
|
||||
let arg = ctx.get_ir(arg).compile(ctx);
|
||||
format!("Nix.force({func})({arg})")
|
||||
}
|
||||
Ir::Call(x) => x.compile(ctx),
|
||||
Ir::Arg(x) => format!("arg{}", x.0),
|
||||
Ir::Let(x) => x.compile(ctx),
|
||||
Ir::Select(x) => x.compile(ctx),
|
||||
&Ir::Thunk(expr_id) => {
|
||||
let inner = ctx.get_ir(expr_id).compile(ctx);
|
||||
format!("Nix.createThunk(()=>({}))", inner)
|
||||
format!("Nix.createThunk(()=>({}),\"expr{}\")", inner, expr_id.0)
|
||||
}
|
||||
&Ir::ExprRef(expr_id) => {
|
||||
format!("expr{}", expr_id.0)
|
||||
@@ -171,6 +167,14 @@ impl Func {
|
||||
}
|
||||
}
|
||||
|
||||
impl<Ctx: CodegenContext> Compile<Ctx> for Call {
|
||||
fn compile(&self, ctx: &Ctx) -> String {
|
||||
let func = ctx.get_ir(self.func).compile(ctx);
|
||||
let arg = ctx.get_ir(self.arg).compile(ctx);
|
||||
format!("Nix.call({func}, {arg})")
|
||||
}
|
||||
}
|
||||
|
||||
impl<Ctx: CodegenContext> Compile<Ctx> for Let {
|
||||
fn compile(&self, ctx: &Ctx) -> String {
|
||||
let info = &self.binding_sccs;
|
||||
|
||||
Reference in New Issue
Block a user