{"id":31205678,"url":"https://github.com/yzw7489757/ceval","last_synced_at":"2025-09-20T18:52:30.372Z","repository":{"id":57147984,"uuid":"267575030","full_name":"yzw7489757/ceval","owner":"yzw7489757","description":"expression eval","archived":false,"fork":false,"pushed_at":"2021-05-13T16:36:24.000Z","size":2161,"stargazers_count":10,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-08-09T03:02:07.632Z","etag":null,"topics":["calculation","ceval","eval","expression","lexical-analysis"],"latest_commit_sha":null,"homepage":"https://yzw7489757.github.io/ceval/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yzw7489757.png","metadata":{"files":{"readme":"README-ZH.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-05-28T11:45:08.000Z","updated_at":"2023-01-05T08:10:18.000Z","dependencies_parsed_at":"2022-09-06T18:10:11.427Z","dependency_job_id":null,"html_url":"https://github.com/yzw7489757/ceval","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/yzw7489757/ceval","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yzw7489757%2Fceval","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yzw7489757%2Fceval/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yzw7489757%2Fceval/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yzw7489757%2Fceval/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yzw7489757","download_url":"https://codeload.github.com/yzw7489757/ceval/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yzw7489757%2Fceval/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":276142878,"owners_count":25592523,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-20T02:00:10.207Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["calculation","ceval","eval","expression","lexical-analysis"],"created_at":"2025-09-20T18:52:29.114Z","updated_at":"2025-09-20T18:52:30.366Z","avatar_url":"https://github.com/yzw7489757.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Ceval\n\n![](https://img.shields.io/npm/dt/ceval?style=flat-square)\n![](https://img.shields.io/npm/dm/ceval?style=flat-square)\n![](https://img.shields.io/npm/dw/ceval?style=flat-square)\n![](https://img.shields.io/npm/l/ceval)\n![](https://img.shields.io/npm/v/ceval)\n![](https://img.shields.io/github/issues/yzw7489757/ceval)\n![CI](https://github.com/yzw7489757/ceval/workflows/CI/badge.svg?branch=master)\n![Node.js CI](https://github.com/yzw7489757/ceval/workflows/Node.js%20CI/badge.svg)\n![](https://img.shields.io/github/size/yzw7489757/ceval/lib/index.js)\n![](https://img.shields.io/travis/yzw7489757/ceval?label=Travis%20Build)\n\n[online demo](https://yzw7489757.github.io/ceval/);\n\n零依赖，适合表达式运算; \n\n``` ts\n┌───────────────────────────────┐\n│                               │\n│   Destination: lib/index.js   │\n│   Bundle Size:  21.92 KB      │\n│   Minified Size:  21.89 KB    │\n│   Gzipped Size:  6.76 KB      │\n│                               │\n└───────────────────────────────┘\n```\n\n## 使用\n\n``` shell\nnpm i ceval -S\n```\n\n## 介绍\n\n![alt=流程图](https://user-images.githubusercontent.com/28922129/83138027-c5541680-a11c-11ea-9ef4-aa2ddfa3884b.png)\n\n### Options\n``` ts\nconst Parser = require('ceval')\nconst analysis = new Parser({\n   /**\n   * @desc 允许使用操作符，不建议改\n   * @type {boolean}\n   */\n  endableOperators?: boolean = true;\n\n  /**\n   * @desc 十进制，默认启用多进制，支持二、八、十六进制\n   * @type {boolean}\n   */\n  endableBitNumber?: boolean = true;\n\n  /**\n   * @desc 允许访问成员 例如 a.b a['b']\n   * @type {boolean}\n   */\n  allowMemberAccess?: boolean = true;\n\n  /**\n   * @desc 默认情况下允许放大计算\n   * @see 以兼容处理算术结果 e.g 0.1+0.2 !== 0.3  || 1.0-0.9 !== 0.1\n   * 边界计算（n \u003e Number.MAX_SAFE_INTEGER || n \u003c Number.MIN_SAFE_INTEGER）不会做处理\n   * @requires false \n   * @type {boolean}\n   */\n  allowHandleNumberPrecision?: boolean = true;\n\n  /**\n   * @desc 默认情况下，不允许预设值覆盖运算符\n   * @see 在某些情况下，如果你希望进行更精确的计算，例如 BigInt、presetValue = {'+': (a, b) =\u003e (a+b)|0 }\n   * @requires false\n   * @type {boolean}\n   * @memberof CevalOptions\n   */\n  allowOperatorsCovered?: boolean;\n\n  /**\n   * @desc 当没有返回值或未定义时触发默认返回值\n   * @type {any}\n   */\n  defaultReturnValues?: any = '' // done\n})\n```\n\n## API\nParser 实例API\n\n| api | desc | type |\n| --- | --- | --- |\n| operatorMap | 运算符映射表，可用于覆盖预置值操作 | Record\u003cstring, Function\u003e|\n| getSupportOperationMap | 查询支持的运算符方法的名称,以支持operatorMap修改 | (ops: string) =\u003e null \\| Function;| \n| parseString | 解析字符串 | (expression: string, values?: Record\u003cstring, any\u003e) =\u003e any;|\n| getCurrentValues | 获取当前数据池预置+外部+内部声明变量 | () =\u003e Record\u003cstring, any\u003e |\n| updatePresetValues| 更新预设值 |(values: Record\u003cstring, any\u003e) =\u003e void|\n| updateOptions| 更新Options | (Options: Partial\\\u003cCevalOptions\u003e) =\u003e void|\n| getOptions| 获取Options | () =\u003e Readonly\\\u003cCevalOptions\u003e|\n\n关于Options示例 [test case](https://github.com/yzw7489757/ceval/blob/master/test/options.test.js);\n\n通过 [TC29/test262](https://github.com/tc39/test262/tree/master/test/language) 大部分测试用例;\n\n## 规则\n\n只有两条规则：\n\n### 结尾分号\n\ne.g.\n``` ts\nparse('0b01 + 0b01;') // 2 \n```\n虽然在一个简单表达式操作中没必要那么麻烦，但确实是一个好习惯。Parser可以准确地知道结尾在哪里，没有什么限制。\n\ne.g.\n```ts\nparse(`\n  function abs(a,b,c) { \n    let b = 1 /* ⚠️ error, must has semicolon */\n    c = 2;\n    return(a+b+c);\n  };\n  abs(3,4,8);\n`)\n```\n\n### 变量\n由var句柄申明的变量不影响 \"scope\"，会被放到全局数据池中。\n而 \"let\" 和 \"const\" 只会分配给当前作用域，如果当前作用域存在则发出警告。但仍然执行复制成功，后续将处理为无视该赋值行为，该变量仍然是赋值前的值。\n\nTODO: 这是个纠结的点，如果你有什么建议欢迎提出。\n``` ts\nvar Parser = require('ceval');\n\nvar instance = new Parser({/*...*/});\nvar parse = instance.parseString;\n\nparse(`\n  var obj = { foo:'foo', bar: 'bar'};\n\n  function abs(a,b,c) {\n    var d = 'global';\n    return (a+b+c);\n  }\n  abs(1,2,3)\n`)\n\nconsole.log(instance.getCurrentValues().obj); // { foo:'foo', bar: 'bar'}\nconsole.log(instance.getCurrentValues().d); // 'global'\n\nparse(`\n  let foo = 'foo';\n  const bar = 'bar';\n  function abs(a,b,c) {\n    let d = 'scope';\n    const e = 'scope';\n    return (a+b+c);\n  }\n  abs(1,2,3)\n`)\nconsole.log(instance.getCurrentValues().foo); // undefined\nconsole.log(instance.getCurrentValues().bar); // undefined\nconsole.log(instance.getCurrentValues().d); // undefined\nconsole.log(instance.getCurrentValues().e); // undefined\n```\n\n## 基本\n\n``` ts\nconst { parse: parse } = analysis\n```\n\n### Number\n``` ts\nparse('0b01') // 1\nparse('0b11') // 3\nparse('0b010101') // 21\n\nparse('01') // 1\nparse('077') // 63\nparse('01111') // 585\n\nparse('.1') // 1\nparse('33') // 33\nparse('100.00') // 100\n\nparse('0x01') // 1\nparse('0xaf') // 175\nparse('0x9fac') // 40876\n\nparse(`1e+308*2 === Infinity`) // true\n\nparse(`\n    var x = NaN;\n    var y = NaN;\n    return (x !== y);\n  `) // true\n\nparse(`\n  var x = NaN;\n  return(typeof(x) === 'number');\n  `) // true\n\nparse(`\n  var x = NaN;\n  var x_geq_0=(x \u003e= 0.0);\n  return(x_geq_0)\n  `) // false\n\nparse(`\n  var x=+Infinity;\n  return(typeof(x) === 'number')\n  `) // true\n```\nMore testcase [here](https://github.com/yzw7489757/ceval/blob/master/test/number.test.js)\n\n### 运算\n``` ts\nconst obj = `{ a: 1, b: 2, c: 3, d: { e: 4, f: 5}}`\nparse(`1+1`);                       // 2\nparse(`-1-2-3`);                    // -6\nparse(`1*2*3`);                     // 6\nparse(`1/2/4`);                     // 0.125\nparse(`undefined || 2`);            // 2\nparse(`~-1 || -2 || 3`);            // -2\nparse(`-0 == +0`);                  // true\nparse(`~1 \u003e 1`);                    // false\nparse(`false \u003e false \u003e 1`);         // false\nparse(`5 \u003e= 0`);                    // true\nparse(`1 in [1, 2, 3]`);            // true\nparse(`undefined in [1, 2, true]`); // false\nparse(`'a' in ${obj}`);             // true\nparse(`\\'\\'a\\'\\' in ${obj}`);       // true ('\"a\"'  === 'a') is Palindrome\nparse(`1 === true`);                // false\nparse(`3%2`);                       // 1\n```\n\n### Function\n``` ts\nparse(`\n  function abs(a,b,c) { \n    var a = 5; /* =\u003e inject to presetValues */\n    let b = 1; /* =\u003e inject to current scope */\n    c = 2;\n    const d = 4; /* If the current scope contains the variable D, It will trigger warning, but the operation will still be completed, is overlay */\n    return(a+b+c);\n  };\n  abs(3,4,8);\n`)\n``` \n\n### Object \u0026 Array\n``` ts\nparse(`[1*2, false, true, undefined, null]`); // Array[]\nparse(`var a = { b: { c: ['a','b','c','d']} };'e' in a.b.c`); // false\nparse(`{ a: 1, b: 2, c: { d: undefined, e: { f: false, g: { h: null }}}}`); // object\n\nparse(`var a = { b: 2 };a.b`) //2;\nparse(`var a = { b: 2 };a[\"b\"]`) //2;\nparse(`var a = { b: 2, c:3 };var b='c';a[b]`) //3;\n\n// data reference\nparse(`\n  var a = { b: 2, c:[1,2,3]};\n  var b='c';\n  a[b][0] = '0';\n  return a[b];\n`) // ['0',2,3]\n\nparse(`\n  var arr = [1,2,3];\n  arr[0] = 0;\n  return arr;\n`) // [0,2,3]\n```\n\n### Variable\n\n``` ts\nparse(`\nvar a = { foo: 1 };\nvar b = { bar: 2 };\nlet a = { state: 1 } // ⚠️, Raise warning, current scope exists key\nconst b = { state: 1 } // ⚠️, Raise warning, current scope exists key\n\nlet c = { coo: 1} // success;\nconst d = { coo: 1} // success;\n`)\n\nparse(`\nvar a = { a: [false, true, undefined, null, ''] };\nvar b = { b: true, c: undefined, d:{ e: a, f: '1', g: {}}};\n`) // Can be obtained from the instance. api: getCurrentValues\n```\n### this\n\u003c!-- TODO: 考虑加入中，仍是个可选的功能。 --\u003e\n\n### 操作符\n通过`instance.operatorMap`获取所有操作符；\n\n#### return \n`return` 中断当前操作轮询；但它不影响外部。\n``` ts\nparse(`\nreturn 1;\nreturn 2;\n`) // 1\n\nparse(`\n  var foo = 'foo'\n  function abs(a,b,c) {\n    return a;\n    return b;\n  }\n  var bar = abs(1,2,3)\n  return (bar + foo);\n`) // foo1\n```\n\n### 其他\n\n请转到测试用例以了解更多信息 [examples](https://github.com/yzw7489757/ceval/tree/master/test)。\n\n### TODO: [Test39](https://github.com/tc39/test262/tree/master/test/language/types) 一些测试用例.\n#### speed of progress\n2020-06-24 done: number, null, boolean\n\n更多功能扩展中，欢迎参与或提出feature。\n\n## development\n\n### develop\n``` shell\nnpm start\n```\n\n### build\n``` shell\n# webapck build umd module, No compression\nnpm run build:umd\n\n# rollup build umd module, Compressed version\nnpm run build:rollup\n\n# webpack build docs\nnpm run build:docs\n```\n\n### publish\n```shell\nnpm publish\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyzw7489757%2Fceval","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyzw7489757%2Fceval","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyzw7489757%2Fceval/lists"}