forked from InKryption/comath
No description
- Zig 100%
|
ssteinbach
502c5e65c3
Use @alignOf to compute alignment
* alignment = 0 is no longer the way to signal default alignment |
||
|---|---|---|
| src | Use @alignOf to compute alignment | |
| .gitignore | Update .gitignore | |
| build.zig | Update to zig master | |
| build.zig.zon | build manifest: bump versions | |
| LICENSE | Add LICENSE (MIT) | |
| README.md |
Remove allow_unused_inputs, add evalWithUnused
|
|
comath: comptime math
The main function this library provides is eval, which is of the form
fneval(comptimeexpr:[]constu8,ctx:anytype,inputs:anytype,)!Eval(expr,@TypeOf(ctx),@TypeOf(inputs))wherein the expr is expected to be source code representing an expression comprised of:
- Identifiers, whose value should be assigned by a field in
inputsof the same name, or be defined by thectx. - Integer, float, or character literals
- Grouped expressions delimited by parentheses
- Field accesses (
expression.identifier|operator symbols) - Index accesses (
expression[expressions]) - Function calls (
expression(expressions)) - Unary operations (
operatorexpression) - Binary operations (
expressionoperatorexpression)
Given an expression that is successfully parsed into an AST at comptime, said AST will then be evaluated.
The semantics of all the operations are defined by the ctx parameter, which should be a type that conforms to a concrete interface,
which can be described in pseudo-code as:
{/// Should return `true` for any string of symbols corresponding to a recognized unary operator.pubinlinefnmatchUnOp(comptimestr:[]constu8)bool{...}/// Should return `true` for any string of symbols corresponding to a recognized binary operator.pubinlinefnmatchBinOp(comptimestr:[]constu8)bool{...}/// Returns the order of the binary operators `lhs` and `rhs`, where `matchBinOp(lhs) = true`, and/// `matchBinOp(rhs) = true`.pubinlinefnorderBinOp(comptimelhs:[]constu8,comptimerhs:[]constu8)?Order{...}/// Determines the value and type of number literals.pubfnEvalNumberLiteral(comptimesrc:[]constu8)type{...}pubfnevalNumberLiteral(comptimesrc:[]constu8)EvalNumberLiteral(src){...}/// Determines the value and type of identifiers, overriding those which would otherwise be/// determined via the `inputs` struct. `EvalIdent` returning `noreturn` causes/// `eval` to instead look for the identifier in the `inputs` struct.pubfnEvalIdent(comptimeident:[]constu8)type{...}pubfnevalIdent(ctx:@This(),comptimeident:[]constu8)!EvalIdent(ident){...}/// Corresponds to `lhs.accessor`.pubfnEvalProperty(comptimeLhs:type,comptimeaccessor:[]constu8)type{...}pubfnevalProperty(ctx:@This(),lhs:anytype,comptimeaccessor:[]constu8)!EvalProperty(@TypeOf(lhs),accessor){...}/// Corresponds to `lhs[rhs...]`, where `rhs` is a tuple whose elements are the list of indices used to access `lhs`.pubfnEvalIndexAccess(comptimeLhs:type,comptimeRhs:type)type{...}pubfnevalIndexAccess(ctx:@This(),lhs:anytype,rhs:anytype)!EvalIndexAccess(@TypeOf(lhs),@TypeOf(rhs)){...}/// Corresponds to `callee(args...)`, where `args` is a tuple whose elements are the arguments to `callee`.pubfnEvalFuncCall(comptimeCallee:type,comptimeArgs:type)type{...}pubfnevalFuncCall(ctx:@This(),callee:anytype,args:anytype)!EvalFuncCall(@TypeOf(callee),@TypeOf(args)){...}/// Corresponds to `op value`./// In most contexts, it should be sufficient to assume `@hasField(UnOp, op)`.pubfnEvalUnOp(comptimeop:[]constu8,comptimeT:type)type{...}pubfnevalUnOp(ctx:@This(),comptimeop:[]constu8,value:anytype)!EvalUnOp(op,@TypeOf(value)){...}/// Corresponds to `lhs op rhs`/// In most contexts, it should be sufficient to assume `@hasField(BinOp, op)`.pubfnEvalBinOp(comptimeLhs:type,comptimeop:[]constu8,comptimeRhs:type)type{...}pubfnevalBinOp(ctx:@This(),lhs:anytype,comptimeop:[]constu8,rhs:anytype)!EvalBinOp(@TypeOf(lhs),op,@TypeOf(rhs)){...}}Some built-in contexts are provided in the contexts namespace, both for use and for reference.
Example code:
conststd=@import("std");constcomath=@import("comath");test{constctx=comath.ctx.simple({});constvalue=comath.eval("a * 2",ctx,.{.a=4})catch|err|switch(err){};trystd.testing.expect(value==8);}Notable Implementations
To see an example of the terse notation enabled by comath, see zilliam.