diff --git a/.gitignore b/.gitignore index 1de5659..6b014a2 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -target \ No newline at end of file +target +*.vsix \ No newline at end of file diff --git a/simfony-ext/.vscodeignore b/simfony-ext/.vscodeignore new file mode 100644 index 0000000..0373327 --- /dev/null +++ b/simfony-ext/.vscodeignore @@ -0,0 +1,4 @@ +.vscode/** +.vscode-test/** +.gitignore +vsc-extension-quickstart.md \ No newline at end of file diff --git a/simfony-ext/LICENSE b/simfony-ext/LICENSE new file mode 100644 index 0000000..4c18ac0 --- /dev/null +++ b/simfony-ext/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 StarkWare Industries Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/simfony-ext/README.md b/simfony-ext/README.md new file mode 100644 index 0000000..82fb100 --- /dev/null +++ b/simfony-ext/README.md @@ -0,0 +1,84 @@ +# Simfony Language Support + +VSCode extension providing syntax highlighting and autocompletion for the Simfony programming language. + +## Features + +- Syntax highlighting for .simf files +- Basic language configuration (brackets, comments) +- Support for C-style preprocessor directives (#include, #define, etc.) +- (Coming soon) Autocompletion for standard library + +## Installation + +### Local Installation + +1. Clone this repository +2. Navigate to the extension directory: + ```bash + cd simfony-ext + ``` +3. Install dependencies: + ```bash + npm install + ``` +4. Package the extension: + ```bash + npm install -g @vscode/vsce + vsce package + ``` + This will create a `.vsix` file in the current directory. + +5. Install the extension in VSCode: + - Launch VS Code + - Go to the Extensions view (Ctrl+Shift+X) + - Click on the "..." menu in the top-right of the Extensions view + - Select "Install from VSIX..." + - Navigate to and select the `.vsix` file you created + +### Alternative Installation Method + +You can also install the extension directly from the source code: + +1. Copy the `simfony-ext` folder to your VSCode extensions directory: + - Windows: `%USERPROFILE%\.vscode\extensions` + - macOS/Linux: `~/.vscode/extensions` + +2. Restart VSCode + +## Development + +1. Clone this repository +2. Run `npm install` +3. Open the project in VS Code +4. Press F5 to start debugging (this will launch a new VSCode window with the extension loaded) +5. Make changes to the extension +6. Reload the debugging window to see your changes (Ctrl+R or Cmd+R) + +## Building from Source + +To build the extension from source: + +1. Install Node.js (v14 or later recommended) +2. Clone this repository +3. Navigate to the extension directory: + ```bash + cd simfony-ext + ``` +4. Install dependencies: + ```bash + npm install + ``` +5. Package the extension: + ```bash + npm install -g @vscode/vsce + vsce package + ``` + +## Contributing + +Contributions are welcome! Please feel free to submit a Pull Request. + +## License + +[MIT](LICENSE) \ No newline at end of file diff --git a/simfony-ext/language-configuration.json b/simfony-ext/language-configuration.json new file mode 100644 index 0000000..a7ce9cf --- /dev/null +++ b/simfony-ext/language-configuration.json @@ -0,0 +1,22 @@ +{ + "comments": { + "lineComment": "//" + }, + "brackets": [ + ["{", "}"], + ["[", "]"], + ["(", ")"] + ], + "autoClosingPairs": [ + { "open": "{", "close": "}" }, + { "open": "[", "close": "]" }, + { "open": "(", "close": ")" }, + { "open": "\"", "close": "\"" } + ], + "surroundingPairs": [ + ["{", "}"], + ["[", "]"], + ["(", ")"], + ["\"", "\""] + ] +} \ No newline at end of file diff --git a/simfony-ext/package-lock.json b/simfony-ext/package-lock.json new file mode 100644 index 0000000..d656073 --- /dev/null +++ b/simfony-ext/package-lock.json @@ -0,0 +1,16 @@ +{ + "name": "simfony-language", + "version": "0.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "simfony-language", + "version": "0.0.1", + "license": "MIT", + "engines": { + "vscode": "^1.85.0" + } + } + } +} diff --git a/simfony-ext/package.json b/simfony-ext/package.json new file mode 100644 index 0000000..b62bfc2 --- /dev/null +++ b/simfony-ext/package.json @@ -0,0 +1,31 @@ +{ + "name": "simfony-language", + "displayName": "Simfony Language Support", + "description": "Syntax highlighting and autocompletion for Simfony language", + "version": "0.0.1", + "publisher": "starkware", + "repository": { + "type": "git", + "url": "https://github.com/keep-starknet-strange/stark-symphony" + }, + "engines": { + "vscode": "^1.85.0" + }, + "categories": [ + "Programming Languages" + ], + "contributes": { + "languages": [{ + "id": "simfony", + "aliases": ["Simfony", "simfony"], + "extensions": [".simf"], + "configuration": "./language-configuration.json" + }], + "grammars": [{ + "language": "simfony", + "scopeName": "source.simfony", + "path": "./syntaxes/simfony.tmLanguage.json" + }] + }, + "license": "MIT" +} \ No newline at end of file diff --git a/simfony-ext/syntaxes/simfony.tmLanguage.json b/simfony-ext/syntaxes/simfony.tmLanguage.json new file mode 100644 index 0000000..52f0812 --- /dev/null +++ b/simfony-ext/syntaxes/simfony.tmLanguage.json @@ -0,0 +1,298 @@ +{ + "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json", + "name": "Simfony", + "patterns": [ + { + "include": "#preprocessor" + }, + { + "include": "#comments" + }, + { + "include": "#keywords" + }, + { + "include": "#functions" + }, + { + "include": "#types" + }, + { + "include": "#literals" + }, + { + "include": "#expressions" + }, + { + "include": "#modules" + } + ], + "repository": { + "preprocessor": { + "patterns": [ + { + "name": "meta.preprocessor.simfony", + "match": "^\\s*#\\s*(include|define|undef|if|ifdef|ifndef|else|elif|endif|line|error|pragma)\\b", + "captures": { + "1": { + "name": "keyword.control.preprocessor.simfony" + } + } + }, + { + "name": "meta.preprocessor.include.simfony", + "match": "^\\s*#\\s*include\\s+([\"<].*[\">])", + "captures": { + "1": { + "name": "string.quoted.other.lt-gt.include.simfony" + } + } + }, + { + "name": "meta.preprocessor.define.simfony", + "begin": "^\\s*#\\s*(define)\\s+([a-zA-Z_][a-zA-Z0-9_]*)", + "beginCaptures": { + "1": { + "name": "keyword.control.preprocessor.simfony" + }, + "2": { + "name": "entity.name.function.preprocessor.simfony" + } + }, + "end": "(?=(?://|/\\*))|$", + "patterns": [ + { + "include": "#preprocessor-expression" + } + ] + }, + { + "name": "meta.preprocessor.macro.simfony", + "begin": "^\\s*#\\s*(define)\\s+([a-zA-Z_][a-zA-Z0-9_]*)\\(", + "beginCaptures": { + "1": { + "name": "keyword.control.preprocessor.simfony" + }, + "2": { + "name": "entity.name.function.preprocessor.simfony" + } + }, + "end": "\\)|(?=(?://|/\\*))|$", + "patterns": [ + { + "name": "variable.parameter.preprocessor.simfony", + "match": "[a-zA-Z_][a-zA-Z0-9_]*" + }, + { + "name": "punctuation.separator.parameters.simfony", + "match": "," + } + ] + }, + { + "name": "meta.preprocessor.conditional.simfony", + "begin": "^\\s*#\\s*(if|ifdef|ifndef|elif)\\b", + "beginCaptures": { + "1": { + "name": "keyword.control.preprocessor.simfony" + } + }, + "end": "(?=(?://|/\\*))|$", + "patterns": [ + { + "include": "#preprocessor-expression" + } + ] + } + ] + }, + "preprocessor-expression": { + "patterns": [ + { + "name": "constant.language.preprocessor.simfony", + "match": "\\b(defined)\\b" + }, + { + "name": "entity.name.function.preprocessor.simfony", + "match": "\\b[a-zA-Z_][a-zA-Z0-9_]*\\b" + }, + { + "include": "#literals" + }, + { + "name": "keyword.operator.preprocessor.simfony", + "match": "&&|\\|\\||==|!=|<=|>=|<|>|!|&&|\\|\\||\\+|\\-|\\*|\\/|%|<<|>>|&|\\||\\^|~" + } + ] + }, + "comments": { + "patterns": [ + { + "name": "comment.line.double-slash.simfony", + "match": "//.*$" + }, + { + "name": "comment.block.simfony", + "begin": "/\\*", + "end": "\\*/" + } + ] + }, + "keywords": { + "patterns": [ + { + "name": "keyword.control.simfony", + "match": "\\b(fn|let|match|mod|type|const)\\b" + }, + { + "name": "keyword.operator.simfony", + "match": "(->|=>|=|:|,|;)" + } + ] + }, + "functions": { + "patterns": [ + { + "name": "entity.name.function.simfony", + "match": "\\b(unwrap_left|unwrap_right|for_while|is_none|unwrap|assert|panic|match|into|fold|dbg)\\b" + }, + { + "match": "\\b(fn)\\s+([a-zA-Z][a-zA-Z0-9_]*)\\s*\\(", + "captures": { + "1": { + "name": "keyword.control.simfony" + }, + "2": { + "name": "entity.name.function.simfony" + } + } + }, + { + "match": "\\b([a-zA-Z][a-zA-Z0-9_]*)\\s*\\(", + "captures": { + "1": { + "name": "entity.name.function.call.simfony" + } + } + } + ] + }, + "types": { + "patterns": [ + { + "name": "storage.type.simfony", + "match": "\\b(Either|Option|bool|List|u128|u256|u16|u32|u64|u1|u2|u4|u8)\\b" + }, + { + "name": "storage.type.builtin.simfony", + "match": "\\b(Ctx8|Pubkey|Message64|Message|Signature|Scalar|Fe|Gej|Ge|Point|Height|Time|Distance|Duration|Lock|Outpoint|Confidential1|ExplicitAsset|Asset1|ExplicitAmount|Amount1|ExplicitNonce|Nonce|TokenAmount1)\\b" + }, + { + "match": "\\b(type)\\s+([a-zA-Z][a-zA-Z0-9_]*)\\s*=", + "captures": { + "1": { + "name": "keyword.control.simfony" + }, + "2": { + "name": "entity.name.type.simfony" + } + } + }, + { + "match": ":\\s*([a-zA-Z][a-zA-Z0-9_]*|Either<.*>|Option<.*>|\\(.*\\)|\\[.*\\]|List<.*>)", + "captures": { + "1": { + "name": "storage.type.simfony" + } + } + } + ] + }, + "literals": { + "patterns": [ + { + "name": "constant.numeric.decimal.simfony", + "match": "\\b[0-9][0-9_]*\\b" + }, + { + "name": "constant.numeric.binary.simfony", + "match": "\\b0b[01_]+\\b" + }, + { + "name": "constant.numeric.hex.simfony", + "match": "\\b0x[0-9a-fA-F_]+\\b" + }, + { + "name": "constant.language.boolean.simfony", + "match": "\\b(true|false)\\b" + }, + { + "name": "constant.language.simfony", + "match": "\\b(None)\\b" + }, + { + "name": "string.quoted.double.simfony", + "begin": "\"", + "end": "\"", + "patterns": [ + { + "name": "constant.character.escape.simfony", + "match": "\\\\." + } + ] + } + ] + }, + "expressions": { + "patterns": [ + { + "name": "variable.other.simfony", + "match": "\\b[a-zA-Z][a-zA-Z0-9_]*\\b" + }, + { + "match": "\\b(Left|Right|Some)\\s*\\(", + "captures": { + "1": { + "name": "support.function.simfony" + } + } + }, + { + "match": "(witness|param)::(\\w+)", + "captures": { + "1": { + "name": "support.type.simfony" + }, + "2": { + "name": "variable.other.simfony" + } + } + }, + { + "match": "jet::(\\w+)", + "captures": { + "1": { + "name": "support.function.simfony" + } + } + } + ] + }, + "modules": { + "patterns": [ + { + "match": "\\b(mod)\\s+(witness|param)\\b", + "captures": { + "1": { + "name": "keyword.control.simfony" + }, + "2": { + "name": "entity.name.module.simfony" + } + } + } + ] + } + }, + "scopeName": "source.simfony" +} \ No newline at end of file diff --git a/src/merkle.simf b/src/merkle.simf index d8bbe83..89b4158 100644 --- a/src/merkle.simf +++ b/src/merkle.simf @@ -9,7 +9,7 @@ /// A proof node is a tuple of a 256-bit value and a boolean indicating whether it is the left or right sibling. type ProofNode = (u256, bool); -/// Compute the next node in the proof. +/// Compute the next intermediate node in the Merkle tree. fn merkle_compute_step(element: ProofNode, acc: u256) -> u256 { let (node, is_left): ProofNode = element; match is_left {