forked from lix-project/lix
* Assertions.
* Logical operators (!, &&, ||, ->).
This commit is contained in:
parent
e17e95a828
commit
fa18f1f184
|
@ -13,11 +13,6 @@ EvalState::EvalState()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Expr getAttr(EvalState & state, Expr e, const string & name)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Substitute an argument set into the body of a function. */
|
/* Substitute an argument set into the body of a function. */
|
||||||
static Expr substArgs(Expr body, ATermList formals, Expr arg)
|
static Expr substArgs(Expr body, ATermList formals, Expr arg)
|
||||||
{
|
{
|
||||||
|
@ -142,7 +137,8 @@ Expr evalExpr2(EvalState & state, Expr e)
|
||||||
ATmatch(e, "Bool(<term>)", &e1) ||
|
ATmatch(e, "Bool(<term>)", &e1) ||
|
||||||
ATmatch(e, "Function([<list>], <term>)", &e1, &e2) ||
|
ATmatch(e, "Function([<list>], <term>)", &e1, &e2) ||
|
||||||
ATmatch(e, "Attrs([<list>])", &e1) ||
|
ATmatch(e, "Attrs([<list>])", &e1) ||
|
||||||
ATmatch(e, "List([<list>])", &e1))
|
ATmatch(e, "List([<list>])", &e1) ||
|
||||||
|
ATmatch(e, "Null", &e1))
|
||||||
return e;
|
return e;
|
||||||
|
|
||||||
/* Any encountered variables must be undeclared or primops. */
|
/* Any encountered variables must be undeclared or primops. */
|
||||||
|
@ -163,6 +159,8 @@ Expr evalExpr2(EvalState & state, Expr e)
|
||||||
if (primop == "derivation") return primDerivation(state, e2);
|
if (primop == "derivation") return primDerivation(state, e2);
|
||||||
if (primop == "toString") return primToString(state, e2);
|
if (primop == "toString") return primToString(state, e2);
|
||||||
if (primop == "baseNameOf") return primBaseNameOf(state, e2);
|
if (primop == "baseNameOf") return primBaseNameOf(state, e2);
|
||||||
|
if (primop == "null") return primNull(state, e2);
|
||||||
|
if (primop == "isNull") return primIsNull(state, e2);
|
||||||
else throw badTerm("undefined variable/primop", e1);
|
else throw badTerm("undefined variable/primop", e1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,13 +198,36 @@ Expr evalExpr2(EvalState & state, Expr e)
|
||||||
return evalExpr(state, e3);
|
return evalExpr(state, e3);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Equality. Just strings for now. */
|
/* Assertions. */
|
||||||
if (ATmatch(e, "OpEq(<term>, <term>)", &e1, &e2)) {
|
if (ATmatch(e, "Assert(<term>, <term>)", &e1, &e2)) {
|
||||||
string s1 = evalString(state, e1);
|
if (!evalBool(state, e1)) throw badTerm("guard failed", e);
|
||||||
string s2 = evalString(state, e2);
|
return evalExpr(state, e2);
|
||||||
return s1 == s2 ? ATmake("Bool(True)") : ATmake("Bool(False)");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Generic equality. */
|
||||||
|
if (ATmatch(e, "OpEq(<term>, <term>)", &e1, &e2))
|
||||||
|
return makeBool(evalExpr(state, e1) == evalExpr(state, e2));
|
||||||
|
|
||||||
|
/* Generic inequality. */
|
||||||
|
if (ATmatch(e, "OpNEq(<term>, <term>)", &e1, &e2))
|
||||||
|
return makeBool(evalExpr(state, e1) != evalExpr(state, e2));
|
||||||
|
|
||||||
|
/* Negation. */
|
||||||
|
if (ATmatch(e, "OpNot(<term>)", &e1))
|
||||||
|
return makeBool(!evalBool(state, e1));
|
||||||
|
|
||||||
|
/* Implication. */
|
||||||
|
if (ATmatch(e, "OpImpl(<term>, <term>)", &e1, &e2))
|
||||||
|
return makeBool(!evalBool(state, e1) || evalBool(state, e2));
|
||||||
|
|
||||||
|
/* Conjunction (logical AND). */
|
||||||
|
if (ATmatch(e, "OpAnd(<term>, <term>)", &e1, &e2))
|
||||||
|
return makeBool(evalBool(state, e1) && evalBool(state, e2));
|
||||||
|
|
||||||
|
/* Disjunction (logical OR). */
|
||||||
|
if (ATmatch(e, "OpOr(<term>, <term>)", &e1, &e2))
|
||||||
|
return makeBool(evalBool(state, e1) || evalBool(state, e2));
|
||||||
|
|
||||||
/* Barf. */
|
/* Barf. */
|
||||||
throw badTerm("invalid expression", e);
|
throw badTerm("invalid expression", e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -222,3 +222,9 @@ Expr substitute(const ATermMap & subs, Expr e)
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Expr makeBool(bool b)
|
||||||
|
{
|
||||||
|
return b ? ATmake("Bool(True)") : ATmake("Bool(False)");
|
||||||
|
}
|
||||||
|
|
|
@ -45,7 +45,6 @@ public:
|
||||||
ATerm string2ATerm(const string & s);
|
ATerm string2ATerm(const string & s);
|
||||||
string aterm2String(ATerm t);
|
string aterm2String(ATerm t);
|
||||||
|
|
||||||
|
|
||||||
/* Generic bottomup traversal over ATerms. The traversal first
|
/* Generic bottomup traversal over ATerms. The traversal first
|
||||||
recursively descends into subterms, and then applies the given term
|
recursively descends into subterms, and then applies the given term
|
||||||
function to the resulting term. */
|
function to the resulting term. */
|
||||||
|
@ -69,5 +68,8 @@ Expr makeAttrs(const ATermMap & attrs);
|
||||||
/* Perform a set of substitutions on an expression. */
|
/* Perform a set of substitutions on an expression. */
|
||||||
Expr substitute(const ATermMap & subs, Expr e);
|
Expr substitute(const ATermMap & subs, Expr e);
|
||||||
|
|
||||||
|
/* Create an expression representing a boolean. */
|
||||||
|
Expr makeBool(bool b);
|
||||||
|
|
||||||
|
|
||||||
#endif /* !__FIXEXPR_H */
|
#endif /* !__FIXEXPR_H */
|
||||||
|
|
|
@ -38,6 +38,8 @@ exports
|
||||||
Id -> Formal {cons("NoDefFormal")}
|
Id -> Formal {cons("NoDefFormal")}
|
||||||
Id "?" Expr -> Formal {cons("DefFormal")}
|
Id "?" Expr -> Formal {cons("DefFormal")}
|
||||||
|
|
||||||
|
"assert" Expr ";" Expr -> Expr {cons("Assert"), right}
|
||||||
|
|
||||||
"rec" "{" Binds "}" -> Expr {cons("Rec")}
|
"rec" "{" Binds "}" -> Expr {cons("Rec")}
|
||||||
"let" "{" Binds "}" -> Expr {cons("LetRec")}
|
"let" "{" Binds "}" -> Expr {cons("LetRec")}
|
||||||
"{" Binds "}" -> Expr {cons("Attrs")}
|
"{" Binds "}" -> Expr {cons("Attrs")}
|
||||||
|
@ -55,7 +57,13 @@ exports
|
||||||
|
|
||||||
"if" Expr "then" Expr "else" Expr -> Expr {cons("If")}
|
"if" Expr "then" Expr "else" Expr -> Expr {cons("If")}
|
||||||
|
|
||||||
Expr "==" Expr -> Expr {cons("OpEq")}
|
Expr "==" Expr -> Expr {cons("OpEq"), non-assoc}
|
||||||
|
Expr "!=" Expr -> Expr {cons("OpNEq"), non-assoc}
|
||||||
|
|
||||||
|
"!" Expr -> Expr {cons("OpNot")}
|
||||||
|
Expr "&&" Expr -> Expr {cons("OpAnd"), right}
|
||||||
|
Expr "||" Expr -> Expr {cons("OpOr"), right}
|
||||||
|
Expr "->" Expr -> Expr {cons("OpImpl"), right}
|
||||||
|
|
||||||
Bool -> Expr {cons("Bool")}
|
Bool -> Expr {cons("Bool")}
|
||||||
|
|
||||||
|
@ -64,6 +72,13 @@ exports
|
||||||
Expr "." Id -> Expr
|
Expr "." Id -> Expr
|
||||||
> Expr ExprList -> ExprList
|
> Expr ExprList -> ExprList
|
||||||
> Expr Expr -> Expr
|
> Expr Expr -> Expr
|
||||||
|
> "!" Expr -> Expr
|
||||||
|
> Expr "==" Expr -> Expr
|
||||||
|
> Expr "!=" Expr -> Expr
|
||||||
|
> Expr "&&" Expr -> Expr
|
||||||
|
> Expr "||" Expr -> Expr
|
||||||
|
> Expr "->" Expr -> Expr
|
||||||
|
> "assert" Expr ";" Expr -> Expr
|
||||||
> "{" {Formal ","}* "}" ":" Expr -> Expr
|
> "{" {Formal ","}* "}" ":" Expr -> Expr
|
||||||
|
|
||||||
|
|
||||||
|
@ -78,6 +93,7 @@ exports
|
||||||
"rec" -> Id {reject}
|
"rec" -> Id {reject}
|
||||||
"true" -> Id {reject}
|
"true" -> Id {reject}
|
||||||
"false" -> Id {reject}
|
"false" -> Id {reject}
|
||||||
|
"assert" -> Id {reject}
|
||||||
|
|
||||||
[0-9]+ -> Int
|
[0-9]+ -> Int
|
||||||
|
|
||||||
|
|
|
@ -225,3 +225,16 @@ Expr primToString(EvalState & state, Expr arg)
|
||||||
return ATmake("Str(<str>)", s);
|
return ATmake("Str(<str>)", s);
|
||||||
else throw badTerm("cannot coerce to string", arg);
|
else throw badTerm("cannot coerce to string", arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Expr primNull(EvalState & state, Expr arg)
|
||||||
|
{
|
||||||
|
return ATmake("Null");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Expr primIsNull(EvalState & state, Expr arg)
|
||||||
|
{
|
||||||
|
arg = evalExpr(state, arg);
|
||||||
|
return makeBool(ATmatch(arg, "Null"));
|
||||||
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
argument. */
|
argument. */
|
||||||
Expr primImport(EvalState & state, Expr arg);
|
Expr primImport(EvalState & state, Expr arg);
|
||||||
|
|
||||||
|
|
||||||
/* Construct (as a unobservable) side effect) a Nix derivation
|
/* Construct (as a unobservable) side effect) a Nix derivation
|
||||||
expression that performs the derivation described by the argument
|
expression that performs the derivation described by the argument
|
||||||
set. Returns the original set extended with the following
|
set. Returns the original set extended with the following
|
||||||
|
@ -18,14 +17,18 @@ Expr primImport(EvalState & state, Expr arg);
|
||||||
derivation. */
|
derivation. */
|
||||||
Expr primDerivation(EvalState & state, Expr args);
|
Expr primDerivation(EvalState & state, Expr args);
|
||||||
|
|
||||||
|
|
||||||
/* Return the base name of the given string, i.e., everything
|
/* Return the base name of the given string, i.e., everything
|
||||||
following the last slash. */
|
following the last slash. */
|
||||||
Expr primBaseNameOf(EvalState & state, Expr arg);
|
Expr primBaseNameOf(EvalState & state, Expr arg);
|
||||||
|
|
||||||
|
|
||||||
/* Convert the argument (which can be a path or a uri) to a string. */
|
/* Convert the argument (which can be a path or a uri) to a string. */
|
||||||
Expr primToString(EvalState & state, Expr arg);
|
Expr primToString(EvalState & state, Expr arg);
|
||||||
|
|
||||||
|
/* Return the null value. */
|
||||||
|
Expr primNull(EvalState & state, Expr arg);
|
||||||
|
|
||||||
|
/* Determine whether the argument is the null value. */
|
||||||
|
Expr primIsNull(EvalState & state, Expr arg);
|
||||||
|
|
||||||
|
|
||||||
#endif /* !__PRIMOPS_H */
|
#endif /* !__PRIMOPS_H */
|
||||||
|
|
Loading…
Reference in a new issue