internal: KCL modules, part 1 (#4149)

Addresses #4080. (Not ready to close it yet.)

# Important

Requires a fix for #4147 before it can work in ZMA.

# Overview

```kcl
// numbers.kcl
export fn inc = (x) => {
  return x + 1
}
```

```kcl
import inc from "numbers.kcl"

answer = inc(41)
```

This also implements multiple imports with optional renaming.

```kcl
import inc, dec from "numbers.kcl"
import identity as id, length as len from "utils.kcl"
```

Note: Imported files _must_ be in the same directory.

Things for a follow-up PR:

- #4147. Currently, we cannot read files in WebAssembly, i.e. ZMA.
- Docs
- Should be an error to `import` anywhere besides the top level. Needs parser restructuring to track the context of a "function body".
- Should be an error to have `export` anywhere besides the top level. It has no effect, but we should tell people it's not valid instead of silently ignoring it.
- Error message for cycle detection is funky because the Rust side doesn't actually know the name of the first file. Message will say "b -> a -> b" instead of "a -> b -> a" when "a" is the top-level file.
- Cache imported files so that they don't need to be re-parsed and re-executed.
This commit is contained in:
Jonathan Tran
2024-10-17 00:48:33 -04:00
committed by GitHub
parent 7d44de0c12
commit 0577b6a984
65 changed files with 1746 additions and 58 deletions

View File

@ -82690,6 +82690,58 @@
},
"BodyItem": {
"oneOf": [
{
"type": "object",
"required": [
"end",
"items",
"path",
"raw_path",
"start",
"type"
],
"properties": {
"type": {
"type": "string",
"enum": [
"ImportStatement"
]
},
"start": {
"type": "integer",
"format": "uint",
"minimum": 0.0
},
"end": {
"type": "integer",
"format": "uint",
"minimum": 0.0
},
"items": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ImportItem"
}
},
"path": {
"type": "string"
},
"raw_path": {
"type": "string"
},
"digest": {
"type": "array",
"items": {
"type": "integer",
"format": "uint8",
"minimum": 0.0
},
"maxItems": 32,
"minItems": 32,
"nullable": true
}
}
},
{
"type": "object",
"required": [
@ -82763,6 +82815,9 @@
"$ref": "#/components/schemas/VariableDeclarator"
}
},
"visibility": {
"$ref": "#/components/schemas/ItemVisibility"
},
"kind": {
"$ref": "#/components/schemas/VariableKind"
},
@ -82822,6 +82877,54 @@
}
]
},
"ImportItem": {
"type": "object",
"required": [
"end",
"name",
"start"
],
"properties": {
"name": {
"description": "Name of the item to import.",
"allOf": [
{
"$ref": "#/components/schemas/Identifier"
}
]
},
"alias": {
"description": "Rename the item using an identifier after \"as\".",
"allOf": [
{
"$ref": "#/components/schemas/Identifier"
}
],
"nullable": true
},
"start": {
"type": "integer",
"format": "uint",
"minimum": 0.0
},
"end": {
"type": "integer",
"format": "uint",
"minimum": 0.0
},
"digest": {
"type": "array",
"items": {
"type": "integer",
"format": "uint8",
"minimum": 0.0
},
"maxItems": 32,
"minItems": 32,
"nullable": true
}
}
},
"Expr": {
"description": "An expression can be evaluated to yield a single KCL value.",
"oneOf": [
@ -84475,6 +84578,13 @@
}
}
},
"ItemVisibility": {
"type": "string",
"enum": [
"default",
"export"
]
},
"VariableKind": {
"oneOf": [
{
@ -86338,6 +86448,58 @@
},
"BodyItem": {
"oneOf": [
{
"type": "object",
"required": [
"end",
"items",
"path",
"raw_path",
"start",
"type"
],
"properties": {
"type": {
"type": "string",
"enum": [
"ImportStatement"
]
},
"start": {
"type": "integer",
"format": "uint",
"minimum": 0.0
},
"end": {
"type": "integer",
"format": "uint",
"minimum": 0.0
},
"items": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ImportItem"
}
},
"path": {
"type": "string"
},
"raw_path": {
"type": "string"
},
"digest": {
"type": "array",
"items": {
"type": "integer",
"format": "uint8",
"minimum": 0.0
},
"maxItems": 32,
"minItems": 32,
"nullable": true
}
}
},
{
"type": "object",
"required": [
@ -86411,6 +86573,9 @@
"$ref": "#/components/schemas/VariableDeclarator"
}
},
"visibility": {
"$ref": "#/components/schemas/ItemVisibility"
},
"kind": {
"$ref": "#/components/schemas/VariableKind"
},
@ -86470,6 +86635,54 @@
}
]
},
"ImportItem": {
"type": "object",
"required": [
"end",
"name",
"start"
],
"properties": {
"name": {
"description": "Name of the item to import.",
"allOf": [
{
"$ref": "#/components/schemas/Identifier"
}
]
},
"alias": {
"description": "Rename the item using an identifier after \"as\".",
"allOf": [
{
"$ref": "#/components/schemas/Identifier"
}
],
"nullable": true
},
"start": {
"type": "integer",
"format": "uint",
"minimum": 0.0
},
"end": {
"type": "integer",
"format": "uint",
"minimum": 0.0
},
"digest": {
"type": "array",
"items": {
"type": "integer",
"format": "uint8",
"minimum": 0.0
},
"maxItems": 32,
"minItems": 32,
"nullable": true
}
}
},
"Expr": {
"description": "An expression can be evaluated to yield a single KCL value.",
"oneOf": [
@ -88123,6 +88336,13 @@
}
}
},
"ItemVisibility": {
"type": "string",
"enum": [
"default",
"export"
]
},
"VariableKind": {
"oneOf": [
{
@ -89990,6 +90210,58 @@
},
"BodyItem": {
"oneOf": [
{
"type": "object",
"required": [
"end",
"items",
"path",
"raw_path",
"start",
"type"
],
"properties": {
"type": {
"type": "string",
"enum": [
"ImportStatement"
]
},
"start": {
"type": "integer",
"format": "uint",
"minimum": 0.0
},
"end": {
"type": "integer",
"format": "uint",
"minimum": 0.0
},
"items": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ImportItem"
}
},
"path": {
"type": "string"
},
"raw_path": {
"type": "string"
},
"digest": {
"type": "array",
"items": {
"type": "integer",
"format": "uint8",
"minimum": 0.0
},
"maxItems": 32,
"minItems": 32,
"nullable": true
}
}
},
{
"type": "object",
"required": [
@ -90063,6 +90335,9 @@
"$ref": "#/components/schemas/VariableDeclarator"
}
},
"visibility": {
"$ref": "#/components/schemas/ItemVisibility"
},
"kind": {
"$ref": "#/components/schemas/VariableKind"
},
@ -90122,6 +90397,54 @@
}
]
},
"ImportItem": {
"type": "object",
"required": [
"end",
"name",
"start"
],
"properties": {
"name": {
"description": "Name of the item to import.",
"allOf": [
{
"$ref": "#/components/schemas/Identifier"
}
]
},
"alias": {
"description": "Rename the item using an identifier after \"as\".",
"allOf": [
{
"$ref": "#/components/schemas/Identifier"
}
],
"nullable": true
},
"start": {
"type": "integer",
"format": "uint",
"minimum": 0.0
},
"end": {
"type": "integer",
"format": "uint",
"minimum": 0.0
},
"digest": {
"type": "array",
"items": {
"type": "integer",
"format": "uint8",
"minimum": 0.0
},
"maxItems": 32,
"minItems": 32,
"nullable": true
}
}
},
"Expr": {
"description": "An expression can be evaluated to yield a single KCL value.",
"oneOf": [
@ -91775,6 +92098,13 @@
}
}
},
"ItemVisibility": {
"type": "string",
"enum": [
"default",
"export"
]
},
"VariableKind": {
"oneOf": [
{
@ -114494,6 +114824,58 @@
},
"BodyItem": {
"oneOf": [
{
"type": "object",
"required": [
"end",
"items",
"path",
"raw_path",
"start",
"type"
],
"properties": {
"type": {
"type": "string",
"enum": [
"ImportStatement"
]
},
"start": {
"type": "integer",
"format": "uint",
"minimum": 0.0
},
"end": {
"type": "integer",
"format": "uint",
"minimum": 0.0
},
"items": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ImportItem"
}
},
"path": {
"type": "string"
},
"raw_path": {
"type": "string"
},
"digest": {
"type": "array",
"items": {
"type": "integer",
"format": "uint8",
"minimum": 0.0
},
"maxItems": 32,
"minItems": 32,
"nullable": true
}
}
},
{
"type": "object",
"required": [
@ -114567,6 +114949,9 @@
"$ref": "#/components/schemas/VariableDeclarator"
}
},
"visibility": {
"$ref": "#/components/schemas/ItemVisibility"
},
"kind": {
"$ref": "#/components/schemas/VariableKind"
},
@ -114626,6 +115011,54 @@
}
]
},
"ImportItem": {
"type": "object",
"required": [
"end",
"name",
"start"
],
"properties": {
"name": {
"description": "Name of the item to import.",
"allOf": [
{
"$ref": "#/components/schemas/Identifier"
}
]
},
"alias": {
"description": "Rename the item using an identifier after \"as\".",
"allOf": [
{
"$ref": "#/components/schemas/Identifier"
}
],
"nullable": true
},
"start": {
"type": "integer",
"format": "uint",
"minimum": 0.0
},
"end": {
"type": "integer",
"format": "uint",
"minimum": 0.0
},
"digest": {
"type": "array",
"items": {
"type": "integer",
"format": "uint8",
"minimum": 0.0
},
"maxItems": 32,
"minItems": 32,
"nullable": true
}
}
},
"Expr": {
"description": "An expression can be evaluated to yield a single KCL value.",
"oneOf": [
@ -116279,6 +116712,13 @@
}
}
},
"ItemVisibility": {
"type": "string",
"enum": [
"default",
"export"
]
},
"VariableKind": {
"oneOf": [
{
@ -118535,6 +118975,58 @@
},
"BodyItem": {
"oneOf": [
{
"type": "object",
"required": [
"end",
"items",
"path",
"raw_path",
"start",
"type"
],
"properties": {
"type": {
"type": "string",
"enum": [
"ImportStatement"
]
},
"start": {
"type": "integer",
"format": "uint",
"minimum": 0.0
},
"end": {
"type": "integer",
"format": "uint",
"minimum": 0.0
},
"items": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ImportItem"
}
},
"path": {
"type": "string"
},
"raw_path": {
"type": "string"
},
"digest": {
"type": "array",
"items": {
"type": "integer",
"format": "uint8",
"minimum": 0.0
},
"maxItems": 32,
"minItems": 32,
"nullable": true
}
}
},
{
"type": "object",
"required": [
@ -118608,6 +119100,9 @@
"$ref": "#/components/schemas/VariableDeclarator"
}
},
"visibility": {
"$ref": "#/components/schemas/ItemVisibility"
},
"kind": {
"$ref": "#/components/schemas/VariableKind"
},
@ -118667,6 +119162,54 @@
}
]
},
"ImportItem": {
"type": "object",
"required": [
"end",
"name",
"start"
],
"properties": {
"name": {
"description": "Name of the item to import.",
"allOf": [
{
"$ref": "#/components/schemas/Identifier"
}
]
},
"alias": {
"description": "Rename the item using an identifier after \"as\".",
"allOf": [
{
"$ref": "#/components/schemas/Identifier"
}
],
"nullable": true
},
"start": {
"type": "integer",
"format": "uint",
"minimum": 0.0
},
"end": {
"type": "integer",
"format": "uint",
"minimum": 0.0
},
"digest": {
"type": "array",
"items": {
"type": "integer",
"format": "uint8",
"minimum": 0.0
},
"maxItems": 32,
"minItems": 32,
"nullable": true
}
}
},
"Expr": {
"description": "An expression can be evaluated to yield a single KCL value.",
"oneOf": [
@ -120320,6 +120863,13 @@
}
}
},
"ItemVisibility": {
"type": "string",
"enum": [
"default",
"export"
]
},
"VariableKind": {
"oneOf": [
{
@ -122183,6 +122733,58 @@
},
"BodyItem": {
"oneOf": [
{
"type": "object",
"required": [
"end",
"items",
"path",
"raw_path",
"start",
"type"
],
"properties": {
"type": {
"type": "string",
"enum": [
"ImportStatement"
]
},
"start": {
"type": "integer",
"format": "uint",
"minimum": 0.0
},
"end": {
"type": "integer",
"format": "uint",
"minimum": 0.0
},
"items": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ImportItem"
}
},
"path": {
"type": "string"
},
"raw_path": {
"type": "string"
},
"digest": {
"type": "array",
"items": {
"type": "integer",
"format": "uint8",
"minimum": 0.0
},
"maxItems": 32,
"minItems": 32,
"nullable": true
}
}
},
{
"type": "object",
"required": [
@ -122256,6 +122858,9 @@
"$ref": "#/components/schemas/VariableDeclarator"
}
},
"visibility": {
"$ref": "#/components/schemas/ItemVisibility"
},
"kind": {
"$ref": "#/components/schemas/VariableKind"
},
@ -122315,6 +122920,54 @@
}
]
},
"ImportItem": {
"type": "object",
"required": [
"end",
"name",
"start"
],
"properties": {
"name": {
"description": "Name of the item to import.",
"allOf": [
{
"$ref": "#/components/schemas/Identifier"
}
]
},
"alias": {
"description": "Rename the item using an identifier after \"as\".",
"allOf": [
{
"$ref": "#/components/schemas/Identifier"
}
],
"nullable": true
},
"start": {
"type": "integer",
"format": "uint",
"minimum": 0.0
},
"end": {
"type": "integer",
"format": "uint",
"minimum": 0.0
},
"digest": {
"type": "array",
"items": {
"type": "integer",
"format": "uint8",
"minimum": 0.0
},
"maxItems": 32,
"minItems": 32,
"nullable": true
}
}
},
"Expr": {
"description": "An expression can be evaluated to yield a single KCL value.",
"oneOf": [
@ -123968,6 +124621,13 @@
}
}
},
"ItemVisibility": {
"type": "string",
"enum": [
"default",
"export"
]
},
"VariableKind": {
"oneOf": [
{
@ -125829,6 +126489,58 @@
},
"BodyItem": {
"oneOf": [
{
"type": "object",
"required": [
"end",
"items",
"path",
"raw_path",
"start",
"type"
],
"properties": {
"type": {
"type": "string",
"enum": [
"ImportStatement"
]
},
"start": {
"type": "integer",
"format": "uint",
"minimum": 0.0
},
"end": {
"type": "integer",
"format": "uint",
"minimum": 0.0
},
"items": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ImportItem"
}
},
"path": {
"type": "string"
},
"raw_path": {
"type": "string"
},
"digest": {
"type": "array",
"items": {
"type": "integer",
"format": "uint8",
"minimum": 0.0
},
"maxItems": 32,
"minItems": 32,
"nullable": true
}
}
},
{
"type": "object",
"required": [
@ -125902,6 +126614,9 @@
"$ref": "#/components/schemas/VariableDeclarator"
}
},
"visibility": {
"$ref": "#/components/schemas/ItemVisibility"
},
"kind": {
"$ref": "#/components/schemas/VariableKind"
},
@ -125961,6 +126676,54 @@
}
]
},
"ImportItem": {
"type": "object",
"required": [
"end",
"name",
"start"
],
"properties": {
"name": {
"description": "Name of the item to import.",
"allOf": [
{
"$ref": "#/components/schemas/Identifier"
}
]
},
"alias": {
"description": "Rename the item using an identifier after \"as\".",
"allOf": [
{
"$ref": "#/components/schemas/Identifier"
}
],
"nullable": true
},
"start": {
"type": "integer",
"format": "uint",
"minimum": 0.0
},
"end": {
"type": "integer",
"format": "uint",
"minimum": 0.0
},
"digest": {
"type": "array",
"items": {
"type": "integer",
"format": "uint8",
"minimum": 0.0
},
"maxItems": 32,
"minItems": 32,
"nullable": true
}
}
},
"Expr": {
"description": "An expression can be evaluated to yield a single KCL value.",
"oneOf": [
@ -127614,6 +128377,13 @@
}
}
},
"ItemVisibility": {
"type": "string",
"enum": [
"default",
"export"
]
},
"VariableKind": {
"oneOf": [
{

View File

@ -18,6 +18,27 @@ layout: manual
## Properties
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `type` |enum: `ImportStatement`| | No |
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
| `items` |`[` [`ImportItem`](/docs/kcl/types/ImportItem) `]`| | No |
| `path` |`string`| | No |
| `raw_path` |`string`| | No |
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
----
**Type:** `object`
## Properties
| Property | Type | Description | Required |
@ -45,6 +66,7 @@ layout: manual
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
| `declarations` |`[` [`VariableDeclarator`](/docs/kcl/types/VariableDeclarator) `]`| | No |
| `visibility` |[`ItemVisibility`](/docs/kcl/types/ItemVisibility)| | No |
| `kind` |[`VariableKind`](/docs/kcl/types/VariableKind)| | No |
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |

View File

@ -0,0 +1,24 @@
---
title: "ImportItem"
excerpt: ""
layout: manual
---
**Type:** `object`
## Properties
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `name` |[`Identifier`](/docs/kcl/types/Identifier)| Name of the item to import. | No |
| `alias` |[`Identifier`](/docs/kcl/types/Identifier)| Rename the item using an identifier after "as". | No |
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |

View File

@ -0,0 +1,16 @@
---
title: "ItemVisibility"
excerpt: ""
layout: manual
---
**enum:** `default`, `export`