adds more math functions and fixes parens (#558)
* nested parens fix Signed-off-by: Jess Frazelle <github@jessfraz.com> * e, tau Signed-off-by: Jess Frazelle <github@jessfraz.com> * docs Signed-off-by: Jess Frazelle <github@jessfraz.com> * remove test w log since that is a stdlib fn now Signed-off-by: Jess Frazelle <github@jessfraz.com> --------- Signed-off-by: Jess Frazelle <github@jessfraz.com>
This commit is contained in:
		@ -9490,6 +9490,24 @@
 | 
			
		||||
    "unpublished": false,
 | 
			
		||||
    "deprecated": false
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "e",
 | 
			
		||||
    "summary": "Return the value of Euler’s number `e`.",
 | 
			
		||||
    "description": "",
 | 
			
		||||
    "tags": [],
 | 
			
		||||
    "args": [],
 | 
			
		||||
    "returnValue": {
 | 
			
		||||
      "name": "",
 | 
			
		||||
      "type": "number",
 | 
			
		||||
      "schema": {
 | 
			
		||||
        "type": "number",
 | 
			
		||||
        "format": "double"
 | 
			
		||||
      },
 | 
			
		||||
      "required": true
 | 
			
		||||
    },
 | 
			
		||||
    "unpublished": false,
 | 
			
		||||
    "deprecated": false
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "extrude",
 | 
			
		||||
    "summary": "Extrudes by a given amount.",
 | 
			
		||||
@ -13183,9 +13201,130 @@
 | 
			
		||||
    "unpublished": false,
 | 
			
		||||
    "deprecated": false
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "ln",
 | 
			
		||||
    "summary": "Computes the natural logarithm of the number.",
 | 
			
		||||
    "description": "",
 | 
			
		||||
    "tags": [],
 | 
			
		||||
    "args": [
 | 
			
		||||
      {
 | 
			
		||||
        "name": "num",
 | 
			
		||||
        "type": "number",
 | 
			
		||||
        "schema": {
 | 
			
		||||
          "type": "number",
 | 
			
		||||
          "format": "double"
 | 
			
		||||
        },
 | 
			
		||||
        "required": true
 | 
			
		||||
      }
 | 
			
		||||
    ],
 | 
			
		||||
    "returnValue": {
 | 
			
		||||
      "name": "",
 | 
			
		||||
      "type": "number",
 | 
			
		||||
      "schema": {
 | 
			
		||||
        "type": "number",
 | 
			
		||||
        "format": "double"
 | 
			
		||||
      },
 | 
			
		||||
      "required": true
 | 
			
		||||
    },
 | 
			
		||||
    "unpublished": false,
 | 
			
		||||
    "deprecated": false
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "log",
 | 
			
		||||
    "summary": "Computes the logarithm of the number with respect to an arbitrary base.",
 | 
			
		||||
    "description": "The result might not be correctly rounded owing to implementation details; `log2()` can produce more accurate results for base 2, and `log10()` can produce more accurate results for base 10.",
 | 
			
		||||
    "tags": [],
 | 
			
		||||
    "args": [
 | 
			
		||||
      {
 | 
			
		||||
        "name": "num",
 | 
			
		||||
        "type": "number",
 | 
			
		||||
        "schema": {
 | 
			
		||||
          "type": "number",
 | 
			
		||||
          "format": "double"
 | 
			
		||||
        },
 | 
			
		||||
        "required": true
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "name": "base",
 | 
			
		||||
        "type": "number",
 | 
			
		||||
        "schema": {
 | 
			
		||||
          "type": "number",
 | 
			
		||||
          "format": "double"
 | 
			
		||||
        },
 | 
			
		||||
        "required": true
 | 
			
		||||
      }
 | 
			
		||||
    ],
 | 
			
		||||
    "returnValue": {
 | 
			
		||||
      "name": "",
 | 
			
		||||
      "type": "number",
 | 
			
		||||
      "schema": {
 | 
			
		||||
        "type": "number",
 | 
			
		||||
        "format": "double"
 | 
			
		||||
      },
 | 
			
		||||
      "required": true
 | 
			
		||||
    },
 | 
			
		||||
    "unpublished": false,
 | 
			
		||||
    "deprecated": false
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "log10",
 | 
			
		||||
    "summary": "Computes the base 10 logarithm of the number.",
 | 
			
		||||
    "description": "",
 | 
			
		||||
    "tags": [],
 | 
			
		||||
    "args": [
 | 
			
		||||
      {
 | 
			
		||||
        "name": "num",
 | 
			
		||||
        "type": "number",
 | 
			
		||||
        "schema": {
 | 
			
		||||
          "type": "number",
 | 
			
		||||
          "format": "double"
 | 
			
		||||
        },
 | 
			
		||||
        "required": true
 | 
			
		||||
      }
 | 
			
		||||
    ],
 | 
			
		||||
    "returnValue": {
 | 
			
		||||
      "name": "",
 | 
			
		||||
      "type": "number",
 | 
			
		||||
      "schema": {
 | 
			
		||||
        "type": "number",
 | 
			
		||||
        "format": "double"
 | 
			
		||||
      },
 | 
			
		||||
      "required": true
 | 
			
		||||
    },
 | 
			
		||||
    "unpublished": false,
 | 
			
		||||
    "deprecated": false
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "log2",
 | 
			
		||||
    "summary": "Computes the base 2 logarithm of the number.",
 | 
			
		||||
    "description": "",
 | 
			
		||||
    "tags": [],
 | 
			
		||||
    "args": [
 | 
			
		||||
      {
 | 
			
		||||
        "name": "num",
 | 
			
		||||
        "type": "number",
 | 
			
		||||
        "schema": {
 | 
			
		||||
          "type": "number",
 | 
			
		||||
          "format": "double"
 | 
			
		||||
        },
 | 
			
		||||
        "required": true
 | 
			
		||||
      }
 | 
			
		||||
    ],
 | 
			
		||||
    "returnValue": {
 | 
			
		||||
      "name": "",
 | 
			
		||||
      "type": "number",
 | 
			
		||||
      "schema": {
 | 
			
		||||
        "type": "number",
 | 
			
		||||
        "format": "double"
 | 
			
		||||
      },
 | 
			
		||||
      "required": true
 | 
			
		||||
    },
 | 
			
		||||
    "unpublished": false,
 | 
			
		||||
    "deprecated": false
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "max",
 | 
			
		||||
    "summary": "Returns the maximum of the given arguments.",
 | 
			
		||||
    "summary": "Computes the maximum of the given arguments.",
 | 
			
		||||
    "description": "",
 | 
			
		||||
    "tags": [],
 | 
			
		||||
    "args": [
 | 
			
		||||
@ -13216,7 +13355,7 @@
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "min",
 | 
			
		||||
    "summary": "Returns the minimum of the given arguments.",
 | 
			
		||||
    "summary": "Computes the minimum of the given arguments.",
 | 
			
		||||
    "description": "",
 | 
			
		||||
    "tags": [],
 | 
			
		||||
    "args": [
 | 
			
		||||
@ -13247,7 +13386,7 @@
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "pi",
 | 
			
		||||
    "summary": "Return the value of `pi`.",
 | 
			
		||||
    "summary": "Return the value of `pi`. Archimedes’ constant (π).",
 | 
			
		||||
    "description": "",
 | 
			
		||||
    "tags": [],
 | 
			
		||||
    "args": [],
 | 
			
		||||
@ -16155,6 +16294,24 @@
 | 
			
		||||
    "unpublished": false,
 | 
			
		||||
    "deprecated": false
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "tau",
 | 
			
		||||
    "summary": "Return the value of `tau`. The full circle constant (τ). Equal to 2π.",
 | 
			
		||||
    "description": "",
 | 
			
		||||
    "tags": [],
 | 
			
		||||
    "args": [],
 | 
			
		||||
    "returnValue": {
 | 
			
		||||
      "name": "",
 | 
			
		||||
      "type": "number",
 | 
			
		||||
      "schema": {
 | 
			
		||||
        "type": "number",
 | 
			
		||||
        "format": "double"
 | 
			
		||||
      },
 | 
			
		||||
      "required": true
 | 
			
		||||
    },
 | 
			
		||||
    "unpublished": false,
 | 
			
		||||
    "deprecated": false
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "xLine",
 | 
			
		||||
    "summary": "Draw a line on the x-axis.",
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										131
									
								
								docs/kcl/std.md
									
									
									
									
									
								
							
							
						
						
									
										131
									
								
								docs/kcl/std.md
									
									
									
									
									
								
							@ -22,6 +22,7 @@
 | 
			
		||||
	* [`ceil`](#ceil)
 | 
			
		||||
	* [`close`](#close)
 | 
			
		||||
	* [`cos`](#cos)
 | 
			
		||||
	* [`e`](#e)
 | 
			
		||||
	* [`extrude`](#extrude)
 | 
			
		||||
	* [`floor`](#floor)
 | 
			
		||||
	* [`getExtrudeWallTransform`](#getExtrudeWallTransform)
 | 
			
		||||
@ -32,6 +33,10 @@
 | 
			
		||||
	* [`legLen`](#legLen)
 | 
			
		||||
	* [`line`](#line)
 | 
			
		||||
	* [`lineTo`](#lineTo)
 | 
			
		||||
	* [`ln`](#ln)
 | 
			
		||||
	* [`log`](#log)
 | 
			
		||||
	* [`log10`](#log10)
 | 
			
		||||
	* [`log2`](#log2)
 | 
			
		||||
	* [`max`](#max)
 | 
			
		||||
	* [`min`](#min)
 | 
			
		||||
	* [`pi`](#pi)
 | 
			
		||||
@ -45,6 +50,7 @@
 | 
			
		||||
	* [`sqrt`](#sqrt)
 | 
			
		||||
	* [`startSketchAt`](#startSketchAt)
 | 
			
		||||
	* [`tan`](#tan)
 | 
			
		||||
	* [`tau`](#tau)
 | 
			
		||||
	* [`xLine`](#xLine)
 | 
			
		||||
	* [`xLineTo`](#xLineTo)
 | 
			
		||||
	* [`yLine`](#yLine)
 | 
			
		||||
@ -1770,6 +1776,25 @@ cos(num: number) -> number
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### e
 | 
			
		||||
 | 
			
		||||
Return the value of Euler’s number `e`.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
e() -> number
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### Arguments
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#### Returns
 | 
			
		||||
 | 
			
		||||
* `number`
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### extrude
 | 
			
		||||
 | 
			
		||||
Extrudes by a given amount.
 | 
			
		||||
@ -2487,9 +2512,90 @@ lineTo(data: LineToData, sketch_group: SketchGroup) -> SketchGroup
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### ln
 | 
			
		||||
 | 
			
		||||
Computes the natural logarithm of the number.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
ln(num: number) -> number
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### Arguments
 | 
			
		||||
 | 
			
		||||
* `num`: `number`
 | 
			
		||||
 | 
			
		||||
#### Returns
 | 
			
		||||
 | 
			
		||||
* `number`
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### log
 | 
			
		||||
 | 
			
		||||
Computes the logarithm of the number with respect to an arbitrary base.
 | 
			
		||||
 | 
			
		||||
The result might not be correctly rounded owing to implementation details; `log2()` can produce more accurate results for base 2, and `log10()` can produce more accurate results for base 10.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
log(num: number, base: number) -> number
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### Arguments
 | 
			
		||||
 | 
			
		||||
* `num`: `number`
 | 
			
		||||
* `base`: `number`
 | 
			
		||||
 | 
			
		||||
#### Returns
 | 
			
		||||
 | 
			
		||||
* `number`
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### log10
 | 
			
		||||
 | 
			
		||||
Computes the base 10 logarithm of the number.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
log10(num: number) -> number
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### Arguments
 | 
			
		||||
 | 
			
		||||
* `num`: `number`
 | 
			
		||||
 | 
			
		||||
#### Returns
 | 
			
		||||
 | 
			
		||||
* `number`
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### log2
 | 
			
		||||
 | 
			
		||||
Computes the base 2 logarithm of the number.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
log2(num: number) -> number
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### Arguments
 | 
			
		||||
 | 
			
		||||
* `num`: `number`
 | 
			
		||||
 | 
			
		||||
#### Returns
 | 
			
		||||
 | 
			
		||||
* `number`
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### max
 | 
			
		||||
 | 
			
		||||
Returns the maximum of the given arguments.
 | 
			
		||||
Computes the maximum of the given arguments.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -2509,7 +2615,7 @@ max(args: [number]) -> number
 | 
			
		||||
 | 
			
		||||
### min
 | 
			
		||||
 | 
			
		||||
Returns the minimum of the given arguments.
 | 
			
		||||
Computes the minimum of the given arguments.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -2529,7 +2635,7 @@ min(args: [number]) -> number
 | 
			
		||||
 | 
			
		||||
### pi
 | 
			
		||||
 | 
			
		||||
Return the value of `pi`.
 | 
			
		||||
Return the value of `pi`. Archimedes’ constant (π).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -3128,6 +3234,25 @@ tan(num: number) -> number
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### tau
 | 
			
		||||
 | 
			
		||||
Return the value of `tau`. The full circle constant (τ). Equal to 2π.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
tau() -> number
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### Arguments
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#### Returns
 | 
			
		||||
 | 
			
		||||
* `number`
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### xLine
 | 
			
		||||
 | 
			
		||||
Draw a line on the x-axis.
 | 
			
		||||
 | 
			
		||||
@ -139,54 +139,6 @@ const newVar = myVar + 1
 | 
			
		||||
      },
 | 
			
		||||
    ])
 | 
			
		||||
  })
 | 
			
		||||
  test('using std function "log"', () => {
 | 
			
		||||
    const code = `log(5, "hello", aIdentifier)`
 | 
			
		||||
    const { body } = parser_wasm(code)
 | 
			
		||||
    expect(body).toEqual([
 | 
			
		||||
      {
 | 
			
		||||
        type: 'ExpressionStatement',
 | 
			
		||||
        start: 0,
 | 
			
		||||
        end: 28,
 | 
			
		||||
        expression: {
 | 
			
		||||
          type: 'CallExpression',
 | 
			
		||||
          start: 0,
 | 
			
		||||
          end: 28,
 | 
			
		||||
          callee: {
 | 
			
		||||
            type: 'Identifier',
 | 
			
		||||
            start: 0,
 | 
			
		||||
            end: 3,
 | 
			
		||||
            name: 'log',
 | 
			
		||||
          },
 | 
			
		||||
          arguments: [
 | 
			
		||||
            {
 | 
			
		||||
              type: 'Literal',
 | 
			
		||||
              start: 4,
 | 
			
		||||
              end: 5,
 | 
			
		||||
              value: 5,
 | 
			
		||||
              raw: '5',
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              type: 'Literal',
 | 
			
		||||
              start: 7,
 | 
			
		||||
              end: 14,
 | 
			
		||||
              value: 'hello',
 | 
			
		||||
              raw: '"hello"',
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              type: 'Identifier',
 | 
			
		||||
              start: 16,
 | 
			
		||||
              end: 27,
 | 
			
		||||
              name: 'aIdentifier',
 | 
			
		||||
            },
 | 
			
		||||
          ],
 | 
			
		||||
          function: {
 | 
			
		||||
            type: 'InMemory',
 | 
			
		||||
          },
 | 
			
		||||
          optional: false,
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
    ])
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
describe('testing function declaration', () => {
 | 
			
		||||
 | 
			
		||||
@ -1203,6 +1203,54 @@ const bracket = startSketchAt([0,0])
 | 
			
		||||
  |> line([leg2, 0], %)
 | 
			
		||||
  |> line([0, -thickness], %)
 | 
			
		||||
  |> line([-leg2 + thickness, 0], %)
 | 
			
		||||
"#;
 | 
			
		||||
        parse_execute(ast).await.unwrap();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[tokio::test(flavor = "multi_thread")]
 | 
			
		||||
    async fn test_math_doubly_nested_parens() {
 | 
			
		||||
        let ast = r#"const sigmaAllow = 35000 // psi
 | 
			
		||||
const width = 4 // inch
 | 
			
		||||
const p = 150 // Force on shelf - lbs
 | 
			
		||||
const distance = 6 // inches
 | 
			
		||||
const FOS = 2
 | 
			
		||||
const leg1 = 5 // inches
 | 
			
		||||
const leg2 = 8 // inches
 | 
			
		||||
const thickness_squared = (distance * p * FOS * 6 / (sigmaAllow - width))
 | 
			
		||||
const thickness = 0.32 // inches. App does not support square root function yet
 | 
			
		||||
const bracket = startSketchAt([0,0])
 | 
			
		||||
    |> line([0, leg1], %)
 | 
			
		||||
  |> line([leg2, 0], %)
 | 
			
		||||
  |> line([0, -thickness], %)
 | 
			
		||||
  |> line([-1 * leg2 + thickness, 0], %)
 | 
			
		||||
  |> line([0, -1 * leg1 + thickness], %)
 | 
			
		||||
  |> close(%)
 | 
			
		||||
  |> extrude(width, %)
 | 
			
		||||
show(bracket)
 | 
			
		||||
"#;
 | 
			
		||||
        parse_execute(ast).await.unwrap();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[tokio::test(flavor = "multi_thread")]
 | 
			
		||||
    async fn test_math_nested_parens_one_less() {
 | 
			
		||||
        let ast = r#"const sigmaAllow = 35000 // psi
 | 
			
		||||
const width = 4 // inch
 | 
			
		||||
const p = 150 // Force on shelf - lbs
 | 
			
		||||
const distance = 6 // inches
 | 
			
		||||
const FOS = 2
 | 
			
		||||
const leg1 = 5 // inches
 | 
			
		||||
const leg2 = 8 // inches
 | 
			
		||||
const thickness_squared = distance * p * FOS * 6 / (sigmaAllow - width)
 | 
			
		||||
const thickness = 0.32 // inches. App does not support square root function yet
 | 
			
		||||
const bracket = startSketchAt([0,0])
 | 
			
		||||
    |> line([0, leg1], %)
 | 
			
		||||
  |> line([leg2, 0], %)
 | 
			
		||||
  |> line([0, -thickness], %)
 | 
			
		||||
  |> line([-1 * leg2 + thickness, 0], %)
 | 
			
		||||
  |> line([0, -1 * leg1 + thickness], %)
 | 
			
		||||
  |> close(%)
 | 
			
		||||
  |> extrude(width, %)
 | 
			
		||||
show(bracket)
 | 
			
		||||
"#;
 | 
			
		||||
        parse_execute(ast).await.unwrap();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -1271,4 +1271,22 @@ mod test {
 | 
			
		||||
        let output = parser.build_tree(&input_tokens, vec![]).unwrap();
 | 
			
		||||
        assert_eq!(output, expected_output);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn test_parse_expression_braces_around_lots_of_math() {
 | 
			
		||||
        let code = "(distance * p * FOS * 6 / (sigmaAllow * width))";
 | 
			
		||||
        let tokens = crate::tokeniser::lexer(code);
 | 
			
		||||
        let mut parser = MathParser::new(&tokens);
 | 
			
		||||
        let result = parser.parse();
 | 
			
		||||
        assert!(result.is_ok());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn test_parse_expression_braces_around_internals_lots_of_math() {
 | 
			
		||||
        let code = "distance * p * FOS * 6 / (sigmaAllow * width)";
 | 
			
		||||
        let tokens = crate::tokeniser::lexer(code);
 | 
			
		||||
        let mut parser = MathParser::new(&tokens);
 | 
			
		||||
        let result = parser.parse();
 | 
			
		||||
        assert!(result.is_ok());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -880,10 +880,12 @@ impl Parser {
 | 
			
		||||
                        last_index: function_expression.last_index,
 | 
			
		||||
                    })
 | 
			
		||||
                } else {
 | 
			
		||||
                    return Err(KclError::Unimplemented(KclErrorDetails {
 | 
			
		||||
                        source_ranges: vec![current_token.into()],
 | 
			
		||||
                        message: "expression with braces".to_string(),
 | 
			
		||||
                    }));
 | 
			
		||||
                    // This is likely a binary expression that starts with a parenthesis.
 | 
			
		||||
                    let binary_expression = self.make_binary_expression(index)?;
 | 
			
		||||
                    Ok(ValueReturn {
 | 
			
		||||
                        value: Value::BinaryExpression(Box::new(binary_expression.expression)),
 | 
			
		||||
                        last_index: binary_expression.last_index,
 | 
			
		||||
                    })
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                return Err(KclError::Unimplemented(KclErrorDetails {
 | 
			
		||||
 | 
			
		||||
@ -58,14 +58,14 @@ fn inner_tan(num: f64) -> Result<f64, KclError> {
 | 
			
		||||
    Ok(num.tan())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Return the value of `pi`.
 | 
			
		||||
/// Return the value of `pi`. Archimedes’ constant (π).
 | 
			
		||||
pub fn pi(args: &mut Args) -> Result<MemoryItem, KclError> {
 | 
			
		||||
    let result = inner_pi()?;
 | 
			
		||||
 | 
			
		||||
    args.make_user_val_from_f64(result)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Return the value of `pi`.
 | 
			
		||||
/// Return the value of `pi`. Archimedes’ constant (π).
 | 
			
		||||
#[stdlib {
 | 
			
		||||
    name = "pi",
 | 
			
		||||
}]
 | 
			
		||||
@ -137,7 +137,7 @@ fn inner_ceil(num: f64) -> Result<f64, KclError> {
 | 
			
		||||
    Ok(num.ceil())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Returns the minimum of the given arguments.
 | 
			
		||||
/// Computes the minimum of the given arguments.
 | 
			
		||||
pub fn min(args: &mut Args) -> Result<MemoryItem, KclError> {
 | 
			
		||||
    let nums = args.get_number_array()?;
 | 
			
		||||
    let result = inner_min(nums);
 | 
			
		||||
@ -145,7 +145,7 @@ pub fn min(args: &mut Args) -> Result<MemoryItem, KclError> {
 | 
			
		||||
    args.make_user_val_from_f64(result)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Returns the minimum of the given arguments.
 | 
			
		||||
/// Computes the minimum of the given arguments.
 | 
			
		||||
#[stdlib {
 | 
			
		||||
    name = "min",
 | 
			
		||||
}]
 | 
			
		||||
@ -160,7 +160,7 @@ fn inner_min(args: Vec<f64>) -> f64 {
 | 
			
		||||
    min
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Returns the maximum of the given arguments.
 | 
			
		||||
/// Computes the maximum of the given arguments.
 | 
			
		||||
pub fn max(args: &mut Args) -> Result<MemoryItem, KclError> {
 | 
			
		||||
    let nums = args.get_number_array()?;
 | 
			
		||||
    let result = inner_max(nums);
 | 
			
		||||
@ -168,7 +168,7 @@ pub fn max(args: &mut Args) -> Result<MemoryItem, KclError> {
 | 
			
		||||
    args.make_user_val_from_f64(result)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Returns the maximum of the given arguments.
 | 
			
		||||
/// Computes the maximum of the given arguments.
 | 
			
		||||
#[stdlib {
 | 
			
		||||
    name = "max",
 | 
			
		||||
}]
 | 
			
		||||
@ -260,3 +260,118 @@ pub fn atan(args: &mut Args) -> Result<MemoryItem, KclError> {
 | 
			
		||||
fn inner_atan(num: f64) -> Result<f64, KclError> {
 | 
			
		||||
    Ok(num.atan())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Computes the logarithm of the number with respect to an arbitrary base.
 | 
			
		||||
///
 | 
			
		||||
/// The result might not be correctly rounded owing to implementation
 | 
			
		||||
/// details; `log2()` can produce more accurate results for base 2,
 | 
			
		||||
/// and `log10()` can produce more accurate results for base 10.
 | 
			
		||||
pub fn log(args: &mut Args) -> Result<MemoryItem, KclError> {
 | 
			
		||||
    let nums = args.get_number_array()?;
 | 
			
		||||
    if nums.len() > 2 {
 | 
			
		||||
        return Err(KclError::Type(KclErrorDetails {
 | 
			
		||||
            message: format!("expected 2 arguments, got {}", nums.len()),
 | 
			
		||||
            source_ranges: vec![args.source_range],
 | 
			
		||||
        }));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if nums.len() <= 1 {
 | 
			
		||||
        return Err(KclError::Type(KclErrorDetails {
 | 
			
		||||
            message: format!("expected 2 arguments, got {}", nums.len()),
 | 
			
		||||
            source_ranges: vec![args.source_range],
 | 
			
		||||
        }));
 | 
			
		||||
    }
 | 
			
		||||
    let result = inner_log(nums[0], nums[1])?;
 | 
			
		||||
 | 
			
		||||
    args.make_user_val_from_f64(result)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Computes the logarithm of the number with respect to an arbitrary base.
 | 
			
		||||
///
 | 
			
		||||
/// The result might not be correctly rounded owing to implementation
 | 
			
		||||
/// details; `log2()` can produce more accurate results for base 2,
 | 
			
		||||
/// and `log10()` can produce more accurate results for base 10.
 | 
			
		||||
#[stdlib {
 | 
			
		||||
    name = "log",
 | 
			
		||||
}]
 | 
			
		||||
fn inner_log(num: f64, base: f64) -> Result<f64, KclError> {
 | 
			
		||||
    Ok(num.log(base))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Computes the base 2 logarithm of the number.
 | 
			
		||||
pub fn log2(args: &mut Args) -> Result<MemoryItem, KclError> {
 | 
			
		||||
    let num = args.get_number()?;
 | 
			
		||||
    let result = inner_log2(num)?;
 | 
			
		||||
 | 
			
		||||
    args.make_user_val_from_f64(result)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Computes the base 2 logarithm of the number.
 | 
			
		||||
#[stdlib {
 | 
			
		||||
    name = "log2",
 | 
			
		||||
}]
 | 
			
		||||
fn inner_log2(num: f64) -> Result<f64, KclError> {
 | 
			
		||||
    Ok(num.log2())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Computes the base 10 logarithm of the number.
 | 
			
		||||
pub fn log10(args: &mut Args) -> Result<MemoryItem, KclError> {
 | 
			
		||||
    let num = args.get_number()?;
 | 
			
		||||
    let result = inner_log10(num)?;
 | 
			
		||||
 | 
			
		||||
    args.make_user_val_from_f64(result)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Computes the base 10 logarithm of the number.
 | 
			
		||||
#[stdlib {
 | 
			
		||||
    name = "log10",
 | 
			
		||||
}]
 | 
			
		||||
fn inner_log10(num: f64) -> Result<f64, KclError> {
 | 
			
		||||
    Ok(num.log10())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Computes the natural logarithm of the number.
 | 
			
		||||
pub fn ln(args: &mut Args) -> Result<MemoryItem, KclError> {
 | 
			
		||||
    let num = args.get_number()?;
 | 
			
		||||
    let result = inner_ln(num)?;
 | 
			
		||||
 | 
			
		||||
    args.make_user_val_from_f64(result)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Computes the natural logarithm of the number.
 | 
			
		||||
#[stdlib {
 | 
			
		||||
    name = "ln",
 | 
			
		||||
}]
 | 
			
		||||
fn inner_ln(num: f64) -> Result<f64, KclError> {
 | 
			
		||||
    Ok(num.ln())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Return the value of Euler’s number `e`.
 | 
			
		||||
pub fn e(args: &mut Args) -> Result<MemoryItem, KclError> {
 | 
			
		||||
    let result = inner_e()?;
 | 
			
		||||
 | 
			
		||||
    args.make_user_val_from_f64(result)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Return the value of Euler’s number `e`.
 | 
			
		||||
#[stdlib {
 | 
			
		||||
    name = "e",
 | 
			
		||||
}]
 | 
			
		||||
fn inner_e() -> Result<f64, KclError> {
 | 
			
		||||
    Ok(std::f64::consts::E)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Return the value of `tau`. The full circle constant (τ). Equal to 2π.
 | 
			
		||||
pub fn tau(args: &mut Args) -> Result<MemoryItem, KclError> {
 | 
			
		||||
    let result = inner_tau()?;
 | 
			
		||||
 | 
			
		||||
    args.make_user_val_from_f64(result)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Return the value of `tau`. The full circle constant (τ). Equal to 2π.
 | 
			
		||||
#[stdlib {
 | 
			
		||||
    name = "tau",
 | 
			
		||||
}]
 | 
			
		||||
fn inner_tau() -> Result<f64, KclError> {
 | 
			
		||||
    Ok(std::f64::consts::TAU)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -68,6 +68,8 @@ impl StdLib {
 | 
			
		||||
            Box::new(crate::std::math::Asin),
 | 
			
		||||
            Box::new(crate::std::math::Atan),
 | 
			
		||||
            Box::new(crate::std::math::Pi),
 | 
			
		||||
            Box::new(crate::std::math::E),
 | 
			
		||||
            Box::new(crate::std::math::Tau),
 | 
			
		||||
            Box::new(crate::std::math::Sqrt),
 | 
			
		||||
            Box::new(crate::std::math::Abs),
 | 
			
		||||
            Box::new(crate::std::math::Floor),
 | 
			
		||||
@ -75,6 +77,10 @@ impl StdLib {
 | 
			
		||||
            Box::new(crate::std::math::Min),
 | 
			
		||||
            Box::new(crate::std::math::Max),
 | 
			
		||||
            Box::new(crate::std::math::Pow),
 | 
			
		||||
            Box::new(crate::std::math::Log),
 | 
			
		||||
            Box::new(crate::std::math::Log2),
 | 
			
		||||
            Box::new(crate::std::math::Log10),
 | 
			
		||||
            Box::new(crate::std::math::Ln),
 | 
			
		||||
        ];
 | 
			
		||||
 | 
			
		||||
        let mut fns = HashMap::new();
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user