feat: __functor
This commit is contained in:
@@ -3,10 +3,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import type { NixValue, NixAttrs, NixBool, NixString } from "./types";
|
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 { isAttrs } from "./builtins/type-check";
|
||||||
import { coerceToString, StringCoercionMode } from "./builtins/conversion";
|
import { coerceToString, StringCoercionMode } from "./builtins/conversion";
|
||||||
import { type NixStringContext, mkStringWithContext } from "./string-context";
|
import { type NixStringContext, mkStringWithContext } from "./string-context";
|
||||||
|
import { force } from "./thunk";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Concatenate multiple values into a string with context
|
* Concatenate multiple values into a string with context
|
||||||
@@ -144,3 +145,20 @@ export const validateParams = (
|
|||||||
|
|
||||||
return forced_arg;
|
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 { 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 { op } from "./operators";
|
||||||
import { builtins, PRIMOP_METADATA } from "./builtins";
|
import { builtins, PRIMOP_METADATA } from "./builtins";
|
||||||
import { coerceToString, StringCoercionMode } from "./builtins/conversion";
|
import { coerceToString, StringCoercionMode } from "./builtins/conversion";
|
||||||
@@ -23,6 +31,7 @@ export const Nix = {
|
|||||||
IS_THUNK,
|
IS_THUNK,
|
||||||
HAS_CONTEXT,
|
HAS_CONTEXT,
|
||||||
|
|
||||||
|
call,
|
||||||
hasAttr,
|
hasAttr,
|
||||||
select,
|
select,
|
||||||
selectWithDefault,
|
selectWithDefault,
|
||||||
|
|||||||
@@ -3,12 +3,21 @@
|
|||||||
* These functions force evaluation and verify the type, throwing errors on mismatch
|
* 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 { isStringWithContext } from "./types";
|
||||||
import { force } from "./thunk";
|
import { force } from "./thunk";
|
||||||
import { getStringValue } from "./string-context";
|
import { getStringValue } from "./string-context";
|
||||||
|
|
||||||
const typeName = (value: NixValue): string => {
|
export const typeName = (value: NixValue): string => {
|
||||||
const val = force(value);
|
const val = force(value);
|
||||||
|
|
||||||
if (typeof val === "bigint") return "int";
|
if (typeof val === "bigint") return "int";
|
||||||
|
|||||||
@@ -49,17 +49,13 @@ impl<Ctx: CodegenContext> Compile<Ctx> for Ir {
|
|||||||
Ir::Func(x) => x.compile(ctx),
|
Ir::Func(x) => x.compile(ctx),
|
||||||
Ir::AttrSet(x) => x.compile(ctx),
|
Ir::AttrSet(x) => x.compile(ctx),
|
||||||
Ir::List(x) => x.compile(ctx),
|
Ir::List(x) => x.compile(ctx),
|
||||||
&Ir::Call(Call { func, arg }) => {
|
Ir::Call(x) => x.compile(ctx),
|
||||||
let func = ctx.get_ir(func).compile(ctx);
|
|
||||||
let arg = ctx.get_ir(arg).compile(ctx);
|
|
||||||
format!("Nix.force({func})({arg})")
|
|
||||||
}
|
|
||||||
Ir::Arg(x) => format!("arg{}", x.0),
|
Ir::Arg(x) => format!("arg{}", x.0),
|
||||||
Ir::Let(x) => x.compile(ctx),
|
Ir::Let(x) => x.compile(ctx),
|
||||||
Ir::Select(x) => x.compile(ctx),
|
Ir::Select(x) => x.compile(ctx),
|
||||||
&Ir::Thunk(expr_id) => {
|
&Ir::Thunk(expr_id) => {
|
||||||
let inner = ctx.get_ir(expr_id).compile(ctx);
|
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) => {
|
&Ir::ExprRef(expr_id) => {
|
||||||
format!("expr{}", expr_id.0)
|
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 {
|
impl<Ctx: CodegenContext> Compile<Ctx> for Let {
|
||||||
fn compile(&self, ctx: &Ctx) -> String {
|
fn compile(&self, ctx: &Ctx) -> String {
|
||||||
let info = &self.binding_sccs;
|
let info = &self.binding_sccs;
|
||||||
|
|||||||
Reference in New Issue
Block a user