diff --git a/.gitattributes b/.gitattributes
deleted file mode 100644
index 4655431d8..000000000
--- a/.gitattributes
+++ /dev/null
@@ -1,6 +0,0 @@
-* text=auto
-
-*.js text eol=lf
-*.c text eol=lf
-*.cpp text eol=lf
-*.h text eol=lf
diff --git a/.github/workflows/njs_clang_test.yml b/.github/workflows/njs_clang_test.yml
deleted file mode 100644
index 7515132c3..000000000
--- a/.github/workflows/njs_clang_test.yml
+++ /dev/null
@@ -1,28 +0,0 @@
-name: CI_NJS_CLANG
-
-on:
- push:
- branches: [ master ]
- pull_request:
- branches: [ master ]
-
-
-jobs:
-
- test:
-
- runs-on: ubuntu-latest
-
- steps:
- - uses: actions/checkout@v2
- - name: Install
- run: |
- git submodule update --init --recursive
- sudo apt install g++ clang
- wget -qO- https://deb.nodesource.com/setup_12.x | sudo -E bash
- sudo apt install -y nodejs
- npm i
- clang++ -v
- - name: run
- run: |
- npm run njs_clang_test
diff --git a/.github/workflows/njs_es3.yml b/.github/workflows/njs_es3.yml
deleted file mode 100644
index e770a2a37..000000000
--- a/.github/workflows/njs_es3.yml
+++ /dev/null
@@ -1,33 +0,0 @@
-name: ES3_NJS
-
-on:
- workflow_dispatch:
- inputs:
- logLevel:
- description: 'Log level'
- required: true
- default: 'warning'
- tags:
- description: 'Test scenario tags'
-
-
-jobs:
-
- test:
-
- runs-on: ubuntu-latest
-
- # Steps represent a sequence of tasks that will be executed as part of the job
- steps:
- # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- - uses: actions/checkout@v2
-
- # Runs a set of commands using the runners shell
- - name: Install and run
- run: |
- sudo apt install g++
- wget -qO- https://deb.nodesource.com/setup_12.x | sudo -E bash
- sudo apt install -y nodejs
- npm i
- npm run es3_test
-
diff --git a/.github/workflows/njs_test.yml b/.github/workflows/njs_test.yml
deleted file mode 100644
index e531e4d59..000000000
--- a/.github/workflows/njs_test.yml
+++ /dev/null
@@ -1,34 +0,0 @@
-name: CI_NJS
-
-on:
- push:
- branches: [ master ]
- pull_request:
- branches: [ master ]
-
-
-jobs:
-
- test:
-
- runs-on: ubuntu-latest
-
- # Steps represent a sequence of tasks that will be executed as part of the job
- steps:
- # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- - uses: actions/checkout@v2
-
- - name: Install
- run: |
- git submodule update --init --recursive
- sudo add-apt-repository ppa:ubuntu-toolchain-r/test
- sudo apt-get update
- sudo apt install g++-10
- wget -qO- https://deb.nodesource.com/setup_12.x | sudo -E bash
- sudo apt install -y nodejs
- npm i
- g++ -v
- - name: run
- run: |
- npm run njs_test
-
diff --git a/.gitignore b/.gitignore
index 81f914263..2fddc7df3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,134 +1 @@
-# Compilations
-.nectar
-.vscode
-*.exe
-*.elf
-*.hex
-*.wasm
-*.asm.js
-
-# Logs
-logs
-*.log
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
-lerna-debug.log*
-
-# Diagnostic reports (https://nodejs.org/api/report.html)
-report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
-
-# Runtime data
-pids
-*.pid
-*.seed
-*.pid.lock
-
-# Directory for instrumented libs generated by jscoverage/JSCover
-lib-cov
-
-# Coverage directory used by tools like istanbul
-coverage
-*.lcov
-
-# nyc test coverage
-.nyc_output
-
-# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
-.grunt
-
-# Bower dependency directory (https://bower.io/)
-bower_components
-
-# node-waf configuration
-.lock-wscript
-
-# Compiled binary addons (https://nodejs.org/api/addons.html)
-build/Release
-
-# Dependency directories
-node_modules/
-jspm_packages/
-
-# Snowpack dependency directory (https://snowpack.dev/)
-web_modules/
-
-# TypeScript cache
-*.tsbuildinfo
-
-# Optional npm cache directory
-.npm
-
-# Optional eslint cache
-.eslintcache
-
-# Microbundle cache
-.rpt2_cache/
-.rts2_cache_cjs/
-.rts2_cache_es/
-.rts2_cache_umd/
-
-# Optional REPL history
-.node_repl_history
-
-# Output of 'npm pack'
-*.tgz
-
-# Yarn Integrity file
-.yarn-integrity
-
-# dotenv environment variables file
-.env
-.env.test
-
-# parcel-bundler cache (https://parceljs.org/)
-.cache
-.parcel-cache
-
-# Next.js build output
-.next
-
-# Nuxt.js build / generate output
-.nuxt
-dist
-
-# Gatsby files
-.cache/
-# Comment in the public line in if your project uses Gatsby and not Next.js
-# https://nextjs.org/blog/next-9-1#public-directory-support
-# public
-
-# vuepress build output
-.vuepress/dist
-
-# Serverless directories
-.serverless/
-
-# Apple
-.DS_Store
-
-# FuseBox cache
-.fusebox/
-
-# DynamoDB Local files
-.dynamodb/
-
-# TernJS port file
-.tern-port
-
-# Stores VSCode versions used for testing VSCode extensions
-.vscode-test
-
-# yarn v2
-
-.yarn/cache
-.yarn/unplugged
-.yarn/build-state.yml
-.pnp.*
-
-
-# MBEDOS
-
-extern/stm32/BUILD/
-__pycache__
-stm32_debug_res.txt
\ No newline at end of file
+.nerd
\ No newline at end of file
diff --git a/.gitmodules b/.gitmodules
deleted file mode 100644
index b22d52ebd..000000000
--- a/.gitmodules
+++ /dev/null
@@ -1,3 +0,0 @@
-[submodule "compiler/native/nectarcpp"]
- path = compiler/native/nectarcpp
- url = https://github.com/nectar-lang/NectarCPP
diff --git a/.npmignore b/.npmignore
deleted file mode 100644
index 35c32fdc6..000000000
--- a/.npmignore
+++ /dev/null
@@ -1,5 +0,0 @@
-tests
-.nectar
-docs
-tests
-.github
\ No newline at end of file
diff --git a/CNAME b/CNAME
deleted file mode 100644
index 01483f41f..000000000
--- a/CNAME
+++ /dev/null
@@ -1 +0,0 @@
-nectar.js.org
\ No newline at end of file
diff --git a/FUNDING.yml b/FUNDING.yml
deleted file mode 100644
index 35a6268f8..000000000
--- a/FUNDING.yml
+++ /dev/null
@@ -1,2 +0,0 @@
-github: nectarjs
-open_collective: nectarjs
diff --git a/LICENSE b/LICENSE
index 25f09638f..030720af6 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
-The MIT License (MIT)
+MIT License
-Copyright (c) 2016-present Adrien THIERRY and other contributors
+Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -18,4 +18,4 @@ 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
+SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 000000000..726983e66
--- /dev/null
+++ b/README.md
@@ -0,0 +1,252 @@
+
+No VM. No Bytecode. No packaging. No Garbage Collector. Fully compiled to native binaries.
+
+
+# NectarJS becomes Nerd
+
+Compile JavaScript and NerdLang in native binaries.
+
+# What is NerdLang
+
+NerdLang is a substract of JS with some additions, focus on efficiency.
+
+**Nerd** is a **JavaScript native compiler** aiming to make JavaScript universal, Nerd is able to compile native apps for Windows, Mac, Linux, iOS, Android, Raspberry, STM32 and more.
+
+> **Nerd** is in active development, join us on [Discord](https://discord.gg/cpe2UuN) if you need more information.
+
+- [Roadmap on Trello](https://trello.com/invite/b/6F4rvEj2/ATTI8842296bacc92724fa8b4114fe1dc80aA9FA431B/nerd)
+
+## Main objectives
+* Supporting EcmaScript 3 standard (then 5, 6 ...)
+* Supporting NodeJS and NPM ecosystem
+* Supporting a maximum of platforms (Windows, Mac, Linux, Android, Arduino, ...)
+* Being secure
+* Embeding debuging tools
+* Compile everything that can be transpiled in JS: Ruby (Opal), Python (Transcript, Brython, JavaScrypthon), TypeScript ...
+
+# Get started
+
+## Installation
+
+### Install GCC/CLang for your platform
+
+- Windows
+Install Mingw and Clang for Windows here: http://winlibs.com/ or Clang here: https://releases.llvm.org/
+
+You can also install Linux for Windows and use a linux system on Windows
+
+You need MinGW with POSIX threads
+
+- Linux / FreeBSD
+Install it with your distro (apt install gcc, yum install gcc, ...).
+You can use GCC, CLANG, as well as any derivative of those compilers (arm-gcc ...)
+
+- Apple iOS
+Install xCode and you are ready.
+
+
+You can check your installation with `npm start njs_test`
+
+## Usage
+
+Simplest way to use Nerd:
+```
+nerd file.js / file.ng
+```
+
+The output file name will be automatically chosen regarding the target. You can specify another output with `-o something.out`
+
+You can select a preset
+```
+nerd file.js --preset [none|speed|size]
+```
+
+You can also run the compiled executable just after compilation using --run:
+```
+nerd file.js --run
+```
+
+You can enable the quiet mode with --quiet:
+```
+nerd file.js --quiet
+```
+
+Changing the stack size (useful on Windows):
+```
+nerd --stack 10000000 flood.js
+```
+
+For more informations about compilation output, use `--verbose`
+
+For help, use `--help`
+
+# Benchmarks
+
+* _Need update_
+
+Compiled with GCC v10.2.0 on Windows
+
+| | NodeJS v12.8.1 | QuickJS 2020-07-05 | Nerd v0.6.104 |
+|-----------|----------------|--------------------|-------------------|
+| sort(1e6) [No preset] |
+| - Time: | 0.33s | - | **0.33s** |
+| - Memory: | 7.0Mb | - | **1.0Mb** |
+|- Filesize:| 28.6Mb | - | **424Kb** |
+| sort(1e6) [+Size preset] |
+|- Filesize:| 28.6Mb | - | **260Kb** |
+| sort(1e6) [+Speed preset] |
+| - Time: | 0.33s | - | **0.20s** |
+| matrix(256) [No preset] |
+| - Time: | 0.33s | - | **0.21s** |
+| - Memory: | 7.0Mb | - | **1.0Mb** |
+|- Filesize:| 28.6Mb | - | **405Kb** |
+| matrix(256) [+Size preset] |
+|- Filesize:| 28.6Mb | - | **251Kb** |
+| matrix(1e6) [+Speed preset] |
+| - Time: | 0.33s | - | **0.11s** |
+
+* _Some code can be evaluated compile-time_
+
+# Supported platforms
+
+Actively tested for
+
+- Windows
+* - win-x86-32
+* - win-x86-64
+- Linux
+* - linux-x86-32
+* - linux-x86-64
+* - linux-arm32v7
+- Arduino
+* - arduino-nano
+* - arduino-uno
+* - arduino-mega1280
+* - arduino-mega2560
+- STM32 Nucleo
+* - nucleo-l152re
+* - nucleo-l432kc
+* - nucleo-f446re
+- Mobile
+* - android
+- Web
+* - wasm
+* - wast
+* - asm-js
+- macOS
+- Sun OS
+
+# Development
+
+This project is in heavy development and a lot features are not implemented yet.
+
+## ECMAScript Support
+
+Nerd already supports more than 80% of ES3.
+
+
+Prototype
+
+
+* .call()
+* .bind()
+
+
+
+
+Array
+
+
+* .length
+* .push(value)
+
+
+
+
+Class
+
+
+* constructor
+* methods
+* static methods
+
+
+
+
+Console
+
+
+* .log(variadic)
+
+
+
+
+JSON
+
+
+* .parse(str)
+* .stringify(obj)
+
+
+
+
+Math **(DONE)**
+
+
+* [All static methods and constants]
+
+
+
+
+Object
+
+
+* .keys
+
+
+
+
+performance
+
+
+* timeOrigin
+* .now()
+
+
+
+
+String
+
+
+* .length
+* .toString()
+* .indexOf(needle)
+* .lastIndexOf(needle)
+* .search(needle)
+* .slice(start, end)
+* .substring(start, end)
+* .substr(start, end)
+* .replace(needle, str)
+
+
+
+
+Syntax
+
+
+* for
+* while / do while
+* if / else if / else
+* try / catch / finally
+* function / lambda
+* class
+* new
+* typeof
+* instanceof
+* undefined
+* null
+* Infinite
+* NaN / isNaN
+* true / false
+
+
\ No newline at end of file
diff --git a/_config.yml b/_config.yml
deleted file mode 100644
index fff4ab923..000000000
--- a/_config.yml
+++ /dev/null
@@ -1 +0,0 @@
-theme: jekyll-theme-minimal
diff --git a/base/cli/cliParser.js b/base/cli/cliParser.js
index af16a9c93..2b752b2b5 100644
--- a/base/cli/cliParser.js
+++ b/base/cli/cliParser.js
@@ -1,11 +1,38 @@
-module.exports = parseCLI;
-function parseCLI(args)
+/*
+ Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
+
+ 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.
+
+*/
+
+
+var parseCLI = function(args)
{
var result = {error: false, msg: "", cli:{}, stack: [], useless: []};
- var useless = [0, 1];
- var withArgs = ["--tmp", "--target", "--spec", "--env", "--stack", "-o", "--preset", "--flash", "--compiler", "-c", "--build", "-b", "--option", "--register", "-r", "--setauthor", "--setid", "--setkey", "--setapi", "--setport", "--sethash", "--setsdk", "--setndk", "--setwin_inc_ucrt", "--setwin_lib_ucrt", "--setwin_lib_um", "--setxcode", "--profile", "-i", "--install", "--init-module", "--author"];
- var noArgs = ["--install_external", "--debug", "--conserve", "--generate", "--config", "--reinit", "--example", "--examples" , "--prepare", "--project", "--run", "--clean", "--purge", "--check", "--no-check", "--verbose", "-v", "--tips", "--version", "--help", "-h", "--release", "--no-undef-error", "--no-undef-warn", "--no-semi-error", "--no-semi-warn", "--no-fast-function", "--no-object-hashmap"];
-
+ var useless = [0];
+ if(!global["__NERD__"])
+ {
+ useless.push(1);
+ }
+
+ var withArgs = ["--target", "--spec", "--env", "--stack", "-o", "--preset", "--flash", "--compiler", "-c", "--build", "-b", "--option", "--register", "-r", "--setauthor", "--setid", "--setkey", "--setapi", "--setport", "--sethash", "--setsdk", "--setndk", "--setwin_inc_ucrt", "--setwin_lib_ucrt", "--setwin_lib_um", "--setxcode"];
+ var noArgs = ["--install_external", "--debug", "--conserve", "--generate", "--config", "--reinit", "--example", "--examples" , "--prepare", "--project", "--run", "--clean", "--purge", "--check", "--no-check", "--verbose", "-v", "--tips", "--version", "--help", "-h", "--release", "--no-object-hashmap"];
for(var i = 0; i < args.length; i++)
{
@@ -47,7 +74,11 @@ function parseCLI(args)
break;
}
}
- else result.stack.push(args[i]);
+ else
+ {
+ result.stack.push(args[i]);
+ }
}
return result;
}
+module.exports = parseCLI;
\ No newline at end of file
diff --git a/base/compiler/target.js b/base/compiler/target.js
index 9247f89ef..cd6bb5a29 100644
--- a/base/compiler/target.js
+++ b/base/compiler/target.js
@@ -1,3 +1,26 @@
+/*
+ Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
+
+ 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.
+
+*/
+
var target = ["win-x86-32", "win-x86-64", "linux-x86-32", "linux-x86-64", "linux-arm32v7",
"arduino-uno", "arduino-mega1280", "arduino-mega2560",
"wasm", "wast", "asm-js",
diff --git a/base/compiler/ts.js b/base/compiler/ts.js
deleted file mode 100644
index 1e34f71d3..000000000
--- a/base/compiler/ts.js
+++ /dev/null
@@ -1,39 +0,0 @@
-var ts = require("typescript");
-
-function compileTS(_code, _file)
-{
- var _program = ts.createProgram([_file], { noResolve: true, module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 });
- const diagnostics = ts.getPreEmitDiagnostics(_program);
-
- for (var i = 0; i < diagnostics.length; i++ )
- {
- var message = diagnostics[i].messageText;
- var file = diagnostics[i].file;
- var filename = file.fileName;
- var error = diagnostics[i].code
-
- var lineAndChar = file.getLineAndCharacterOfPosition(
- diagnostics[i].start
- );
-
- var line = lineAndChar.line + 1;
- var character = lineAndChar.character + 1;
-
- console.log(`${_file}:${line}:${character} - error TS${error}: ${message}`);
- }
-
- if(diagnostics.length)
- {
- console.log();
- if(diagnostics.length == 1) console.log(`Found ${diagnostics.length} error`);
- else console.log(`Found ${diagnostics.length} errors`);
- console.log();
- process.exit(1);
- }
-
- else _code = ts.transpileModule(_code, { compilerOptions: { noResolve: true, module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 } });;
-
- return _code.outputText;
-}
-
-module.exports = compileTS;
diff --git a/base/squel/package.json b/base/squel/package.json
deleted file mode 100644
index 0d4ee8cff..000000000
--- a/base/squel/package.json
+++ /dev/null
@@ -1,47 +0,0 @@
-{
- "name": "{{MODULE_NAME}}",
- "description": "NectarJS {{MODULE_NAME}} module",
- "main": "index.js",
- "bugs":
- {
- "url": "https://github.com/{{AUTHOR}}/{{MODULE_NAME}}/issues"
- },
-
- "directories":
- {
- "root": "."
- },
- "homepage": "https://github.com/{{AUTHOR}}/{{MODULE_NAME}}#readme",
- "keywords":
- [
- "nectarjs",
- "js",
- "javascript"
- ],
- "license": "MIT",
- "licenses": [
- {
- "type": "MIT",
- "url": "https://github.com/{{AUTHOR}}/{{MODULE_NAME}}/blob/master/LICENSE"
- }
- ],
- "repository":
- {
- "type": "git",
- "url": "git+ssh://git@github.com/{{AUTHOR}}/{{MODULE_NAME}}.git"
- },
- "version": "0.0.1",
- "nectar":
- {
- "comment":
- {
-
- },
- "env": ["std", "android", "ios", "node", "arduino", "wasm", "stm32", "esp32"],
- "read_only": [],
- "lib":
- {
-
- }
- }
-}
diff --git a/base/util/adm-zip/MIT-LICENSE.txt b/base/util/adm-zip/MIT-LICENSE.txt
deleted file mode 100644
index 6fe2ba7e6..000000000
--- a/base/util/adm-zip/MIT-LICENSE.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-Copyright (c) 2012 Another-D-Mention Software and other contributors,
-http://www.another-d-mention.ro/
-
-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.
diff --git a/base/util/adm-zip/adm-zip.js b/base/util/adm-zip/adm-zip.js
deleted file mode 100644
index a55d7947a..000000000
--- a/base/util/adm-zip/adm-zip.js
+++ /dev/null
@@ -1,536 +0,0 @@
-var Utils = require("./util");
-var fs = Utils.FileSystem.require(),
- pth = require("path");
-
-fs.existsSync = fs.existsSync || pth.existsSync;
-
-var ZipEntry = require("./zipEntry"),
- ZipFile = require("./zipFile");
-
-var isWin = /^win/.test(process.platform);
-
-
-module.exports = function (/*String*/input) {
- var _zip = undefined,
- _filename = "";
-
- if (input && typeof input === "string") { // load zip file
- if (fs.existsSync(input)) {
- _filename = input;
- _zip = new ZipFile(input, Utils.Constants.FILE);
- } else {
- throw Utils.Errors.INVALID_FILENAME;
- }
- } else if (input && Buffer.isBuffer(input)) { // load buffer
- _zip = new ZipFile(input, Utils.Constants.BUFFER);
- } else { // create new zip file
- _zip = new ZipFile(null, Utils.Constants.NONE);
- }
-
- function sanitize(prefix, name) {
- prefix = pth.resolve(pth.normalize(prefix));
- var parts = name.split('/');
- for (var i = 0, l = parts.length; i < l; i++) {
- var path = pth.normalize(pth.join(prefix, parts.slice(i, l).join(pth.sep)));
- if (path.indexOf(prefix) === 0) {
- return path;
- }
- }
- return pth.normalize(pth.join(prefix, pth.basename(name)));
- }
-
- function getEntry(/*Object*/entry) {
- if (entry && _zip) {
- var item;
- // If entry was given as a file name
- if (typeof entry === "string")
- item = _zip.getEntry(entry);
- // if entry was given as a ZipEntry object
- if (typeof entry === "object" && typeof entry.entryName !== "undefined" && typeof entry.header !== "undefined")
- item = _zip.getEntry(entry.entryName);
-
- if (item) {
- return item;
- }
- }
- return null;
- }
-
- return {
- /**
- * Extracts the given entry from the archive and returns the content as a Buffer object
- * @param entry ZipEntry object or String with the full path of the entry
- *
- * @return Buffer or Null in case of error
- */
- readFile: function (/*Object*/entry) {
- var item = getEntry(entry);
- return item && item.getData() || null;
- },
-
- /**
- * Asynchronous readFile
- * @param entry ZipEntry object or String with the full path of the entry
- * @param callback
- *
- * @return Buffer or Null in case of error
- */
- readFileAsync: function (/*Object*/entry, /*Function*/callback) {
- var item = getEntry(entry);
- if (item) {
- item.getDataAsync(callback);
- } else {
- callback(null, "getEntry failed for:" + entry)
- }
- },
-
- /**
- * Extracts the given entry from the archive and returns the content as plain text in the given encoding
- * @param entry ZipEntry object or String with the full path of the entry
- * @param encoding Optional. If no encoding is specified utf8 is used
- *
- * @return String
- */
- readAsText: function (/*Object*/entry, /*String - Optional*/encoding) {
- var item = getEntry(entry);
- if (item) {
- var data = item.getData();
- if (data && data.length) {
- return data.toString(encoding || "utf8");
- }
- }
- return "";
- },
-
- /**
- * Asynchronous readAsText
- * @param entry ZipEntry object or String with the full path of the entry
- * @param callback
- * @param encoding Optional. If no encoding is specified utf8 is used
- *
- * @return String
- */
- readAsTextAsync: function (/*Object*/entry, /*Function*/callback, /*String - Optional*/encoding) {
- var item = getEntry(entry);
- if (item) {
- item.getDataAsync(function (data) {
- if (data && data.length) {
- callback(data.toString(encoding || "utf8"));
- } else {
- callback("");
- }
- })
- } else {
- callback("");
- }
- },
-
- /**
- * Remove the entry from the file or the entry and all it's nested directories and files if the given entry is a directory
- *
- * @param entry
- */
- deleteFile: function (/*Object*/entry) { // @TODO: test deleteFile
- var item = getEntry(entry);
- if (item) {
- _zip.deleteEntry(item.entryName);
- }
- },
-
- /**
- * Adds a comment to the zip. The zip must be rewritten after adding the comment.
- *
- * @param comment
- */
- addZipComment: function (/*String*/comment) { // @TODO: test addZipComment
- _zip.comment = comment;
- },
-
- /**
- * Returns the zip comment
- *
- * @return String
- */
- getZipComment: function () {
- return _zip.comment || '';
- },
-
- /**
- * Adds a comment to a specified zipEntry. The zip must be rewritten after adding the comment
- * The comment cannot exceed 65535 characters in length
- *
- * @param entry
- * @param comment
- */
- addZipEntryComment: function (/*Object*/entry, /*String*/comment) {
- var item = getEntry(entry);
- if (item) {
- item.comment = comment;
- }
- },
-
- /**
- * Returns the comment of the specified entry
- *
- * @param entry
- * @return String
- */
- getZipEntryComment: function (/*Object*/entry) {
- var item = getEntry(entry);
- if (item) {
- return item.comment || '';
- }
- return ''
- },
-
- /**
- * Updates the content of an existing entry inside the archive. The zip must be rewritten after updating the content
- *
- * @param entry
- * @param content
- */
- updateFile: function (/*Object*/entry, /*Buffer*/content) {
- var item = getEntry(entry);
- if (item) {
- item.setData(content);
- }
- },
-
- /**
- * Adds a file from the disk to the archive
- *
- * @param localPath File to add to zip
- * @param zipPath Optional path inside the zip
- * @param zipName Optional name for the file
- */
- addLocalFile: function (/*String*/localPath, /*String*/zipPath, /*String*/zipName) {
- if (fs.existsSync(localPath)) {
- if (zipPath) {
- zipPath = zipPath.split("\\").join("/");
- if (zipPath.charAt(zipPath.length - 1) !== "/") {
- zipPath += "/";
- }
- } else {
- zipPath = "";
- }
- var p = localPath.split("\\").join("/").split("/").pop();
-
- if (zipName) {
- this.addFile(zipPath + zipName, fs.readFileSync(localPath), "", 0)
- } else {
- this.addFile(zipPath + p, fs.readFileSync(localPath), "", 0)
- }
- } else {
- throw Utils.Errors.FILE_NOT_FOUND.replace("%s", localPath);
- }
- },
-
- /**
- * Adds a local directory and all its nested files and directories to the archive
- *
- * @param localPath
- * @param zipPath optional path inside zip
- * @param filter optional RegExp or Function if files match will
- * be included.
- */
- addLocalFolder: function (/*String*/localPath, /*String*/zipPath, /*RegExp|Function*/filter) {
- if (filter === undefined) {
- filter = function () {
- return true;
- };
- } else if (filter instanceof RegExp) {
- filter = function (filter) {
- return function (filename) {
- return filter.test(filename);
- }
- }(filter);
- }
-
- if (zipPath) {
- zipPath = zipPath.split("\\").join("/");
- if (zipPath.charAt(zipPath.length - 1) !== "/") {
- zipPath += "/";
- }
- } else {
- zipPath = "";
- }
- // normalize the path first
- localPath = pth.normalize(localPath);
- localPath = localPath.split("\\").join("/"); //windows fix
- if (localPath.charAt(localPath.length - 1) !== "/")
- localPath += "/";
-
- if (fs.existsSync(localPath)) {
-
- var items = Utils.findFiles(localPath),
- self = this;
-
- if (items.length) {
- items.forEach(function (path) {
- var p = path.split("\\").join("/").replace(new RegExp(localPath.replace(/(\(|\))/g, '\\$1'), 'i'), ""); //windows fix
- if (filter(p)) {
- if (p.charAt(p.length - 1) !== "/") {
- self.addFile(zipPath + p, fs.readFileSync(path), "", 0)
- } else {
- self.addFile(zipPath + p, Buffer.alloc(0), "", 0)
- }
- }
- });
- }
- } else {
- throw Utils.Errors.FILE_NOT_FOUND.replace("%s", localPath);
- }
- },
-
- /**
- * Allows you to create a entry (file or directory) in the zip file.
- * If you want to create a directory the entryName must end in / and a null buffer should be provided.
- * Comment and attributes are optional
- *
- * @param entryName
- * @param content
- * @param comment
- * @param attr
- */
- addFile: function (/*String*/entryName, /*Buffer*/content, /*String*/comment, /*Number*/attr) {
- var entry = new ZipEntry();
- entry.entryName = entryName;
- entry.comment = comment || "";
-
- if (!attr) {
- if (entry.isDirectory) {
- attr = (0o40755 << 16) | 0x10; // (permissions drwxr-xr-x) + (MS-DOS directory flag)
- } else {
- attr = 0o644 << 16; // permissions -r-wr--r--
- }
- }
-
- entry.attr = attr;
-
- entry.setData(content);
- _zip.setEntry(entry);
- },
-
- /**
- * Returns an array of ZipEntry objects representing the files and folders inside the archive
- *
- * @return Array
- */
- getEntries: function () {
- if (_zip) {
- return _zip.entries;
- } else {
- return [];
- }
- },
-
- /**
- * Returns a ZipEntry object representing the file or folder specified by ``name``.
- *
- * @param name
- * @return ZipEntry
- */
- getEntry: function (/*String*/name) {
- return getEntry(name);
- },
-
- /**
- * Extracts the given entry to the given targetPath
- * If the entry is a directory inside the archive, the entire directory and it's subdirectories will be extracted
- *
- * @param entry ZipEntry object or String with the full path of the entry
- * @param targetPath Target folder where to write the file
- * @param maintainEntryPath If maintainEntryPath is true and the entry is inside a folder, the entry folder
- * will be created in targetPath as well. Default is TRUE
- * @param overwrite If the file already exists at the target path, the file will be overwriten if this is true.
- * Default is FALSE
- *
- * @return Boolean
- */
- extractEntryTo: function (/*Object*/entry, /*String*/targetPath, /*Boolean*/maintainEntryPath, /*Boolean*/overwrite) {
- overwrite = overwrite || false;
- maintainEntryPath = typeof maintainEntryPath === "undefined" ? true : maintainEntryPath;
-
- var item = getEntry(entry);
- if (!item) {
- throw Utils.Errors.NO_ENTRY;
- }
-
- var entryName = item.entryName;
-
- var target = sanitize(targetPath, pth.resolve(targetPath, maintainEntryPath ? entryName : pth.basename(entryName)));
-
- if (item.isDirectory) {
- target = pth.resolve(target, "..");
- var children = _zip.getEntryChildren(item);
- children.forEach(function (child) {
- if (child.isDirectory) return;
- var content = child.getData();
- if (!content) {
- throw Utils.Errors.CANT_EXTRACT_FILE;
- }
- var childName = sanitize(targetPath, child.entryName);
-
- Utils.writeFileTo(pth.resolve(targetPath, maintainEntryPath ? childName : childName.substr(entryName.length)), content, overwrite);
- });
- return true;
- }
-
- var content = item.getData();
- if (!content) throw Utils.Errors.CANT_EXTRACT_FILE;
-
- if (fs.existsSync(target) && !overwrite) {
- throw Utils.Errors.CANT_OVERRIDE;
- }
- Utils.writeFileTo(target, content, overwrite);
-
- return true;
- },
-
- /**
- * Test the archive
- *
- */
- test: function () {
- if (!_zip) {
- return false;
- }
-
- for (var entry in _zip.entries) {
- try {
- if (entry.isDirectory) {
- continue;
- }
- var content = _zip.entries[entry].getData();
- if (!content) {
- return false;
- }
- } catch (err) {
- return false;
- }
- }
- return true;
- },
-
- /**
- * Extracts the entire archive to the given location
- *
- * @param targetPath Target location
- * @param overwrite If the file already exists at the target path, the file will be overwriten if this is true.
- * Default is FALSE
- */
- extractAllTo: function (/*String*/targetPath, /*Boolean*/overwrite) {
- overwrite = overwrite || false;
- if (!_zip) {
- throw Utils.Errors.NO_ZIP;
- }
- _zip.entries.forEach(function (entry) {
- var entryName = sanitize(targetPath, entry.entryName.toString());
- if (entry.isDirectory) {
- Utils.makeDir(entryName);
- return;
- }
- var content = entry.getData();
- if (!content) {
- throw Utils.Errors.CANT_EXTRACT_FILE;
- }
- Utils.writeFileTo(entryName, content, overwrite);
- fs.utimesSync(entryName, entry.header.time, entry.header.time)
- })
- },
-
- /**
- * Asynchronous extractAllTo
- *
- * @param targetPath Target location
- * @param overwrite If the file already exists at the target path, the file will be overwriten if this is true.
- * Default is FALSE
- * @param callback
- */
- extractAllToAsync: function (/*String*/targetPath, /*Boolean*/overwrite, /*Function*/callback) {
- if (!callback) {
- callback = function() {}
- }
- overwrite = overwrite || false;
- if (!_zip) {
- callback(new Error(Utils.Errors.NO_ZIP));
- return;
- }
-
- var entries = _zip.entries;
- var i = entries.length;
- entries.forEach(function (entry) {
- if (i <= 0) return; // Had an error already
-
- var entryName = pth.normalize(entry.entryName.toString());
-
- if (entry.isDirectory) {
- Utils.makeDir(sanitize(targetPath, entryName));
- if (--i === 0)
- callback(undefined);
- return;
- }
- entry.getDataAsync(function (content) {
- if (i <= 0) return;
- if (!content) {
- i = 0;
- callback(new Error(Utils.Errors.CANT_EXTRACT_FILE));
- return;
- }
-
- Utils.writeFileToAsync(sanitize(targetPath, entryName), content, overwrite, function (succ) {
- fs.utimesSync(pth.resolve(targetPath, entryName), entry.header.time, entry.header.time);
- if (i <= 0) return;
- if (!succ) {
- i = 0;
- callback(new Error('Unable to write'));
- return;
- }
- if (--i === 0)
- callback(undefined);
- });
- });
- })
- },
-
- /**
- * Writes the newly created zip file to disk at the specified location or if a zip was opened and no ``targetFileName`` is provided, it will overwrite the opened zip
- *
- * @param targetFileName
- * @param callback
- */
- writeZip: function (/*String*/targetFileName, /*Function*/callback) {
- if (arguments.length === 1) {
- if (typeof targetFileName === "function") {
- callback = targetFileName;
- targetFileName = "";
- }
- }
-
- if (!targetFileName && _filename) {
- targetFileName = _filename;
- }
- if (!targetFileName) return;
-
- var zipData = _zip.compressToBuffer();
- if (zipData) {
- var ok = Utils.writeFileTo(targetFileName, zipData, true);
- if (typeof callback === 'function') callback(!ok ? new Error("failed") : null, "");
- }
- },
-
- /**
- * Returns the content of the entire zip file as a Buffer object
- *
- * @return Buffer
- */
- toBuffer: function (/*Function*/onSuccess, /*Function*/onFail, /*Function*/onItemStart, /*Function*/onItemEnd) {
- this.valueOf = 2;
- if (typeof onSuccess === "function") {
- _zip.toAsyncBuffer(onSuccess, onFail, onItemStart, onItemEnd);
- return null;
- }
- return _zip.compressToBuffer()
- }
- }
-};
diff --git a/base/util/adm-zip/headers/entryHeader.js b/base/util/adm-zip/headers/entryHeader.js
deleted file mode 100644
index 476ba222f..000000000
--- a/base/util/adm-zip/headers/entryHeader.js
+++ /dev/null
@@ -1,261 +0,0 @@
-var Utils = require("../util"),
- Constants = Utils.Constants;
-
-/* The central directory file header */
-module.exports = function () {
- var _verMade = 0x0A,
- _version = 0x0A,
- _flags = 0,
- _method = 0,
- _time = 0,
- _crc = 0,
- _compressedSize = 0,
- _size = 0,
- _fnameLen = 0,
- _extraLen = 0,
-
- _comLen = 0,
- _diskStart = 0,
- _inattr = 0,
- _attr = 0,
- _offset = 0;
-
- var _dataHeader = {};
-
- function setTime(val) {
- val = new Date(val);
- _time = (val.getFullYear() - 1980 & 0x7f) << 25 // b09-16 years from 1980
- | (val.getMonth() + 1) << 21 // b05-08 month
- | val.getDate() << 16 // b00-04 hour
-
- // 2 bytes time
- | val.getHours() << 11 // b11-15 hour
- | val.getMinutes() << 5 // b05-10 minute
- | val.getSeconds() >> 1; // b00-04 seconds divided by 2
- }
-
- setTime(+new Date());
-
- return {
- get made () { return _verMade; },
- set made (val) { _verMade = val; },
-
- get version () { return _version; },
- set version (val) { _version = val },
-
- get flags () { return _flags },
- set flags (val) { _flags = val; },
-
- get method () { return _method; },
- set method (val) { _method = val; },
-
- get time () { return new Date(
- ((_time >> 25) & 0x7f) + 1980,
- ((_time >> 21) & 0x0f) - 1,
- (_time >> 16) & 0x1f,
- (_time >> 11) & 0x1f,
- (_time >> 5) & 0x3f,
- (_time & 0x1f) << 1
- );
- },
- set time (val) {
- setTime(val);
- },
-
- get crc () { return _crc; },
- set crc (val) { _crc = val; },
-
- get compressedSize () { return _compressedSize; },
- set compressedSize (val) { _compressedSize = val; },
-
- get size () { return _size; },
- set size (val) { _size = val; },
-
- get fileNameLength () { return _fnameLen; },
- set fileNameLength (val) { _fnameLen = val; },
-
- get extraLength () { return _extraLen },
- set extraLength (val) { _extraLen = val; },
-
- get commentLength () { return _comLen },
- set commentLength (val) { _comLen = val },
-
- get diskNumStart () { return _diskStart },
- set diskNumStart (val) { _diskStart = val },
-
- get inAttr () { return _inattr },
- set inAttr (val) { _inattr = val },
-
- get attr () { return _attr },
- set attr (val) { _attr = val },
-
- get offset () { return _offset },
- set offset (val) { _offset = val },
-
- get encripted () { return (_flags & 1) === 1 },
-
- get entryHeaderSize () {
- return Constants.CENHDR + _fnameLen + _extraLen + _comLen;
- },
-
- get realDataOffset () {
- return _offset + Constants.LOCHDR + _dataHeader.fnameLen + _dataHeader.extraLen;
- },
-
- get dataHeader () {
- return _dataHeader;
- },
-
- loadDataHeaderFromBinary : function(/*Buffer*/input) {
- var data = input.slice(_offset, _offset + Constants.LOCHDR);
- // 30 bytes and should start with "PK\003\004"
- if (data.readUInt32LE(0) !== Constants.LOCSIG) {
- throw Utils.Errors.INVALID_LOC;
- }
- _dataHeader = {
- // version needed to extract
- version : data.readUInt16LE(Constants.LOCVER),
- // general purpose bit flag
- flags : data.readUInt16LE(Constants.LOCFLG),
- // compression method
- method : data.readUInt16LE(Constants.LOCHOW),
- // modification time (2 bytes time, 2 bytes date)
- time : data.readUInt32LE(Constants.LOCTIM),
- // uncompressed file crc-32 value
- crc : data.readUInt32LE(Constants.LOCCRC),
- // compressed size
- compressedSize : data.readUInt32LE(Constants.LOCSIZ),
- // uncompressed size
- size : data.readUInt32LE(Constants.LOCLEN),
- // filename length
- fnameLen : data.readUInt16LE(Constants.LOCNAM),
- // extra field length
- extraLen : data.readUInt16LE(Constants.LOCEXT)
- }
- },
-
- loadFromBinary : function(/*Buffer*/data) {
- // data should be 46 bytes and start with "PK 01 02"
- if (data.length !== Constants.CENHDR || data.readUInt32LE(0) !== Constants.CENSIG) {
- throw Utils.Errors.INVALID_CEN;
- }
- // version made by
- _verMade = data.readUInt16LE(Constants.CENVEM);
- // version needed to extract
- _version = data.readUInt16LE(Constants.CENVER);
- // encrypt, decrypt flags
- _flags = data.readUInt16LE(Constants.CENFLG);
- // compression method
- _method = data.readUInt16LE(Constants.CENHOW);
- // modification time (2 bytes time, 2 bytes date)
- _time = data.readUInt32LE(Constants.CENTIM);
- // uncompressed file crc-32 value
- _crc = data.readUInt32LE(Constants.CENCRC);
- // compressed size
- _compressedSize = data.readUInt32LE(Constants.CENSIZ);
- // uncompressed size
- _size = data.readUInt32LE(Constants.CENLEN);
- // filename length
- _fnameLen = data.readUInt16LE(Constants.CENNAM);
- // extra field length
- _extraLen = data.readUInt16LE(Constants.CENEXT);
- // file comment length
- _comLen = data.readUInt16LE(Constants.CENCOM);
- // volume number start
- _diskStart = data.readUInt16LE(Constants.CENDSK);
- // internal file attributes
- _inattr = data.readUInt16LE(Constants.CENATT);
- // external file attributes
- _attr = data.readUInt32LE(Constants.CENATX);
- // LOC header offset
- _offset = data.readUInt32LE(Constants.CENOFF);
- },
-
- dataHeaderToBinary : function() {
- // LOC header size (30 bytes)
- var data = Buffer.alloc(Constants.LOCHDR);
- // "PK\003\004"
- data.writeUInt32LE(Constants.LOCSIG, 0);
- // version needed to extract
- data.writeUInt16LE(_version, Constants.LOCVER);
- // general purpose bit flag
- data.writeUInt16LE(_flags, Constants.LOCFLG);
- // compression method
- data.writeUInt16LE(_method, Constants.LOCHOW);
- // modification time (2 bytes time, 2 bytes date)
- data.writeUInt32LE(_time, Constants.LOCTIM);
- // uncompressed file crc-32 value
- data.writeUInt32LE(_crc, Constants.LOCCRC);
- // compressed size
- data.writeUInt32LE(_compressedSize, Constants.LOCSIZ);
- // uncompressed size
- data.writeUInt32LE(_size, Constants.LOCLEN);
- // filename length
- data.writeUInt16LE(_fnameLen, Constants.LOCNAM);
- // extra field length
- data.writeUInt16LE(_extraLen, Constants.LOCEXT);
- return data;
- },
-
- entryHeaderToBinary : function() {
- // CEN header size (46 bytes)
- var data = Buffer.alloc(Constants.CENHDR + _fnameLen + _extraLen + _comLen);
- // "PK\001\002"
- data.writeUInt32LE(Constants.CENSIG, 0);
- // version made by
- data.writeUInt16LE(_verMade, Constants.CENVEM);
- // version needed to extract
- data.writeUInt16LE(_version, Constants.CENVER);
- // encrypt, decrypt flags
- data.writeUInt16LE(_flags, Constants.CENFLG);
- // compression method
- data.writeUInt16LE(_method, Constants.CENHOW);
- // modification time (2 bytes time, 2 bytes date)
- data.writeUInt32LE(_time, Constants.CENTIM);
- // uncompressed file crc-32 value
- data.writeUInt32LE(_crc, Constants.CENCRC);
- // compressed size
- data.writeUInt32LE(_compressedSize, Constants.CENSIZ);
- // uncompressed size
- data.writeUInt32LE(_size, Constants.CENLEN);
- // filename length
- data.writeUInt16LE(_fnameLen, Constants.CENNAM);
- // extra field length
- data.writeUInt16LE(_extraLen, Constants.CENEXT);
- // file comment length
- data.writeUInt16LE(_comLen, Constants.CENCOM);
- // volume number start
- data.writeUInt16LE(_diskStart, Constants.CENDSK);
- // internal file attributes
- data.writeUInt16LE(_inattr, Constants.CENATT);
- // external file attributes
- data.writeUInt32LE(_attr, Constants.CENATX);
- // LOC header offset
- data.writeUInt32LE(_offset, Constants.CENOFF);
- // fill all with
- data.fill(0x00, Constants.CENHDR);
- return data;
- },
-
- toString : function() {
- return '{\n' +
- '\t"made" : ' + _verMade + ",\n" +
- '\t"version" : ' + _version + ",\n" +
- '\t"flags" : ' + _flags + ",\n" +
- '\t"method" : ' + Utils.methodToString(_method) + ",\n" +
- '\t"time" : ' + this.time + ",\n" +
- '\t"crc" : 0x' + _crc.toString(16).toUpperCase() + ",\n" +
- '\t"compressedSize" : ' + _compressedSize + " bytes,\n" +
- '\t"size" : ' + _size + " bytes,\n" +
- '\t"fileNameLength" : ' + _fnameLen + ",\n" +
- '\t"extraLength" : ' + _extraLen + " bytes,\n" +
- '\t"commentLength" : ' + _comLen + " bytes,\n" +
- '\t"diskNumStart" : ' + _diskStart + ",\n" +
- '\t"inAttr" : ' + _inattr + ",\n" +
- '\t"attr" : ' + _attr + ",\n" +
- '\t"offset" : ' + _offset + ",\n" +
- '\t"entryHeaderSize" : ' + (Constants.CENHDR + _fnameLen + _extraLen + _comLen) + " bytes\n" +
- '}';
- }
- }
-};
diff --git a/base/util/adm-zip/headers/index.js b/base/util/adm-zip/headers/index.js
deleted file mode 100644
index b54a7222f..000000000
--- a/base/util/adm-zip/headers/index.js
+++ /dev/null
@@ -1,2 +0,0 @@
-exports.EntryHeader = require("./entryHeader");
-exports.MainHeader = require("./mainHeader");
diff --git a/base/util/adm-zip/headers/mainHeader.js b/base/util/adm-zip/headers/mainHeader.js
deleted file mode 100644
index 3a21d938a..000000000
--- a/base/util/adm-zip/headers/mainHeader.js
+++ /dev/null
@@ -1,80 +0,0 @@
-var Utils = require("../util"),
- Constants = Utils.Constants;
-
-/* The entries in the end of central directory */
-module.exports = function () {
- var _volumeEntries = 0,
- _totalEntries = 0,
- _size = 0,
- _offset = 0,
- _commentLength = 0;
-
- return {
- get diskEntries () { return _volumeEntries },
- set diskEntries (/*Number*/val) { _volumeEntries = _totalEntries = val; },
-
- get totalEntries () { return _totalEntries },
- set totalEntries (/*Number*/val) { _totalEntries = _volumeEntries = val; },
-
- get size () { return _size },
- set size (/*Number*/val) { _size = val; },
-
- get offset () { return _offset },
- set offset (/*Number*/val) { _offset = val; },
-
- get commentLength () { return _commentLength },
- set commentLength (/*Number*/val) { _commentLength = val; },
-
- get mainHeaderSize () {
- return Constants.ENDHDR + _commentLength;
- },
-
- loadFromBinary : function(/*Buffer*/data) {
- // data should be 22 bytes and start with "PK 05 06"
- if (data.length !== Constants.ENDHDR || data.readUInt32LE(0) !== Constants.ENDSIG)
- throw Utils.Errors.INVALID_END;
-
- // number of entries on this volume
- _volumeEntries = data.readUInt16LE(Constants.ENDSUB);
- // total number of entries
- _totalEntries = data.readUInt16LE(Constants.ENDTOT);
- // central directory size in bytes
- _size = data.readUInt32LE(Constants.ENDSIZ);
- // offset of first CEN header
- _offset = data.readUInt32LE(Constants.ENDOFF);
- // zip file comment length
- _commentLength = data.readUInt16LE(Constants.ENDCOM);
- },
-
- toBinary : function() {
- var b = Buffer.alloc(Constants.ENDHDR + _commentLength);
- // "PK 05 06" signature
- b.writeUInt32LE(Constants.ENDSIG, 0);
- b.writeUInt32LE(0, 4);
- // number of entries on this volume
- b.writeUInt16LE(_volumeEntries, Constants.ENDSUB);
- // total number of entries
- b.writeUInt16LE(_totalEntries, Constants.ENDTOT);
- // central directory size in bytes
- b.writeUInt32LE(_size, Constants.ENDSIZ);
- // offset of first CEN header
- b.writeUInt32LE(_offset, Constants.ENDOFF);
- // zip file comment length
- b.writeUInt16LE(_commentLength, Constants.ENDCOM);
- // fill comment memory with spaces so no garbage is left there
- b.fill(" ", Constants.ENDHDR);
-
- return b;
- },
-
- toString : function() {
- return '{\n' +
- '\t"diskEntries" : ' + _volumeEntries + ",\n" +
- '\t"totalEntries" : ' + _totalEntries + ",\n" +
- '\t"size" : ' + _size + " bytes,\n" +
- '\t"offset" : 0x' + _offset.toString(16).toUpperCase() + ",\n" +
- '\t"commentLength" : 0x' + _commentLength + "\n" +
- '}';
- }
- }
-};
\ No newline at end of file
diff --git a/base/util/adm-zip/methods/deflater.js b/base/util/adm-zip/methods/deflater.js
deleted file mode 100644
index 67ecd8866..000000000
--- a/base/util/adm-zip/methods/deflater.js
+++ /dev/null
@@ -1,31 +0,0 @@
-module.exports = function (/*Buffer*/inbuf) {
-
- var zlib = require("zlib");
-
- var opts = {chunkSize: (parseInt(inbuf.length / 1024) + 1) * 1024};
-
- return {
- deflate: function () {
- return zlib.deflateRawSync(inbuf, opts);
- },
-
- deflateAsync: function (/*Function*/callback) {
- var tmp = zlib.createDeflateRaw(opts), parts = [], total = 0;
- tmp.on('data', function (data) {
- parts.push(data);
- total += data.length;
- });
- tmp.on('end', function () {
- var buf = Buffer.alloc(total), written = 0;
- buf.fill(0);
- for (var i = 0; i < parts.length; i++) {
- var part = parts[i];
- part.copy(buf, written);
- written += part.length;
- }
- callback && callback(buf);
- });
- tmp.end(inbuf);
- }
- }
-};
diff --git a/base/util/adm-zip/methods/index.js b/base/util/adm-zip/methods/index.js
deleted file mode 100644
index 58c718da6..000000000
--- a/base/util/adm-zip/methods/index.js
+++ /dev/null
@@ -1,2 +0,0 @@
-exports.Deflater = require("./deflater");
-exports.Inflater = require("./inflater");
\ No newline at end of file
diff --git a/base/util/adm-zip/methods/inflater.js b/base/util/adm-zip/methods/inflater.js
deleted file mode 100644
index a274e4ef5..000000000
--- a/base/util/adm-zip/methods/inflater.js
+++ /dev/null
@@ -1,29 +0,0 @@
-module.exports = function (/*Buffer*/inbuf) {
-
- var zlib = require("zlib");
-
- return {
- inflate: function () {
- return zlib.inflateRawSync(inbuf);
- },
-
- inflateAsync: function (/*Function*/callback) {
- var tmp = zlib.createInflateRaw(), parts = [], total = 0;
- tmp.on('data', function (data) {
- parts.push(data);
- total += data.length;
- });
- tmp.on('end', function () {
- var buf = Buffer.alloc(total), written = 0;
- buf.fill(0);
- for (var i = 0; i < parts.length; i++) {
- var part = parts[i];
- part.copy(buf, written);
- written += part.length;
- }
- callback && callback(buf);
- });
- tmp.end(inbuf);
- }
- }
-};
diff --git a/base/util/adm-zip/package.json b/base/util/adm-zip/package.json
deleted file mode 100644
index af51901fc..000000000
--- a/base/util/adm-zip/package.json
+++ /dev/null
@@ -1,34 +0,0 @@
-{
- "name": "adm-zip",
- "version": "0.4.12",
- "description": "Javascript implementation of zip for nodejs with support for electron original-fs. Allows user to create or extract zip files both in memory or to/from disk",
- "keywords": [
- "zip",
- "methods",
- "archive",
- "unzip"
- ],
- "homepage": "https://github.com/cthackers/adm-zip",
- "author": "Nasca Iacob (https://github.com/cthackers)",
- "bugs": {
- "email": "sy@another-d-mention.ro",
- "url": "https://github.com/cthackers/adm-zip/issues"
- },
- "license": "MIT",
- "files": [
- "adm-zip.js",
- "headers",
- "methods",
- "util",
- "zipEntry.js",
- "zipFile.js"
- ],
- "main": "adm-zip.js",
- "repository": {
- "type": "git",
- "url": "https://github.com/cthackers/adm-zip.git"
- },
- "engines": {
- "node": ">=0.3.0"
- }
-}
\ No newline at end of file
diff --git a/base/util/adm-zip/util/constants.js b/base/util/adm-zip/util/constants.js
deleted file mode 100644
index 02de1e9ad..000000000
--- a/base/util/adm-zip/util/constants.js
+++ /dev/null
@@ -1,115 +0,0 @@
-module.exports = {
- /* The local file header */
- LOCHDR : 30, // LOC header size
- LOCSIG : 0x04034b50, // "PK\003\004"
- LOCVER : 4, // version needed to extract
- LOCFLG : 6, // general purpose bit flag
- LOCHOW : 8, // compression method
- LOCTIM : 10, // modification time (2 bytes time, 2 bytes date)
- LOCCRC : 14, // uncompressed file crc-32 value
- LOCSIZ : 18, // compressed size
- LOCLEN : 22, // uncompressed size
- LOCNAM : 26, // filename length
- LOCEXT : 28, // extra field length
-
- /* The Data descriptor */
- EXTSIG : 0x08074b50, // "PK\007\008"
- EXTHDR : 16, // EXT header size
- EXTCRC : 4, // uncompressed file crc-32 value
- EXTSIZ : 8, // compressed size
- EXTLEN : 12, // uncompressed size
-
- /* The central directory file header */
- CENHDR : 46, // CEN header size
- CENSIG : 0x02014b50, // "PK\001\002"
- CENVEM : 4, // version made by
- CENVER : 6, // version needed to extract
- CENFLG : 8, // encrypt, decrypt flags
- CENHOW : 10, // compression method
- CENTIM : 12, // modification time (2 bytes time, 2 bytes date)
- CENCRC : 16, // uncompressed file crc-32 value
- CENSIZ : 20, // compressed size
- CENLEN : 24, // uncompressed size
- CENNAM : 28, // filename length
- CENEXT : 30, // extra field length
- CENCOM : 32, // file comment length
- CENDSK : 34, // volume number start
- CENATT : 36, // internal file attributes
- CENATX : 38, // external file attributes (host system dependent)
- CENOFF : 42, // LOC header offset
-
- /* The entries in the end of central directory */
- ENDHDR : 22, // END header size
- ENDSIG : 0x06054b50, // "PK\005\006"
- ENDSUB : 8, // number of entries on this disk
- ENDTOT : 10, // total number of entries
- ENDSIZ : 12, // central directory size in bytes
- ENDOFF : 16, // offset of first CEN header
- ENDCOM : 20, // zip file comment length
-
- /* Compression methods */
- STORED : 0, // no compression
- SHRUNK : 1, // shrunk
- REDUCED1 : 2, // reduced with compression factor 1
- REDUCED2 : 3, // reduced with compression factor 2
- REDUCED3 : 4, // reduced with compression factor 3
- REDUCED4 : 5, // reduced with compression factor 4
- IMPLODED : 6, // imploded
- // 7 reserved
- DEFLATED : 8, // deflated
- ENHANCED_DEFLATED: 9, // enhanced deflated
- PKWARE : 10,// PKWare DCL imploded
- // 11 reserved
- BZIP2 : 12, // compressed using BZIP2
- // 13 reserved
- LZMA : 14, // LZMA
- // 15-17 reserved
- IBM_TERSE : 18, // compressed using IBM TERSE
- IBM_LZ77 : 19, //IBM LZ77 z
-
- /* General purpose bit flag */
- FLG_ENC : 0, // encripted file
- FLG_COMP1 : 1, // compression option
- FLG_COMP2 : 2, // compression option
- FLG_DESC : 4, // data descriptor
- FLG_ENH : 8, // enhanced deflation
- FLG_STR : 16, // strong encryption
- FLG_LNG : 1024, // language encoding
- FLG_MSK : 4096, // mask header values
-
- /* Load type */
- FILE : 0,
- BUFFER : 1,
- NONE : 2,
-
- /* 4.5 Extensible data fields */
- EF_ID : 0,
- EF_SIZE : 2,
-
- /* Header IDs */
- ID_ZIP64 : 0x0001,
- ID_AVINFO : 0x0007,
- ID_PFS : 0x0008,
- ID_OS2 : 0x0009,
- ID_NTFS : 0x000a,
- ID_OPENVMS : 0x000c,
- ID_UNIX : 0x000d,
- ID_FORK : 0x000e,
- ID_PATCH : 0x000f,
- ID_X509_PKCS7 : 0x0014,
- ID_X509_CERTID_F : 0x0015,
- ID_X509_CERTID_C : 0x0016,
- ID_STRONGENC : 0x0017,
- ID_RECORD_MGT : 0x0018,
- ID_X509_PKCS7_RL : 0x0019,
- ID_IBM1 : 0x0065,
- ID_IBM2 : 0x0066,
- ID_POSZIP : 0x4690,
-
- EF_ZIP64_OR_32 : 0xffffffff,
- EF_ZIP64_OR_16 : 0xffff,
- EF_ZIP64_SUNCOMP : 0,
- EF_ZIP64_SCOMP : 8,
- EF_ZIP64_RHO : 16,
- EF_ZIP64_DSN : 24
-};
diff --git a/base/util/adm-zip/util/errors.js b/base/util/adm-zip/util/errors.js
deleted file mode 100644
index 50931c318..000000000
--- a/base/util/adm-zip/util/errors.js
+++ /dev/null
@@ -1,35 +0,0 @@
-module.exports = {
- /* Header error messages */
- "INVALID_LOC" : "Invalid LOC header (bad signature)",
- "INVALID_CEN" : "Invalid CEN header (bad signature)",
- "INVALID_END" : "Invalid END header (bad signature)",
-
- /* ZipEntry error messages*/
- "NO_DATA" : "Nothing to decompress",
- "BAD_CRC" : "CRC32 checksum failed",
- "FILE_IN_THE_WAY" : "There is a file in the way: %s",
- "UNKNOWN_METHOD" : "Invalid/unsupported compression method",
-
- /* Inflater error messages */
- "AVAIL_DATA" : "inflate::Available inflate data did not terminate",
- "INVALID_DISTANCE" : "inflate::Invalid literal/length or distance code in fixed or dynamic block",
- "TO_MANY_CODES" : "inflate::Dynamic block code description: too many length or distance codes",
- "INVALID_REPEAT_LEN" : "inflate::Dynamic block code description: repeat more than specified lengths",
- "INVALID_REPEAT_FIRST" : "inflate::Dynamic block code description: repeat lengths with no first length",
- "INCOMPLETE_CODES" : "inflate::Dynamic block code description: code lengths codes incomplete",
- "INVALID_DYN_DISTANCE": "inflate::Dynamic block code description: invalid distance code lengths",
- "INVALID_CODES_LEN": "inflate::Dynamic block code description: invalid literal/length code lengths",
- "INVALID_STORE_BLOCK" : "inflate::Stored block length did not match one's complement",
- "INVALID_BLOCK_TYPE" : "inflate::Invalid block type (type == 3)",
-
- /* ADM-ZIP error messages */
- "CANT_EXTRACT_FILE" : "Could not extract the file",
- "CANT_OVERRIDE" : "Target file already exists",
- "NO_ZIP" : "No zip file was loaded",
- "NO_ENTRY" : "Entry doesn't exist",
- "DIRECTORY_CONTENT_ERROR" : "A directory cannot have content",
- "FILE_NOT_FOUND" : "File not found: %s",
- "NOT_IMPLEMENTED" : "Not implemented",
- "INVALID_FILENAME" : "Invalid filename",
- "INVALID_FORMAT" : "Invalid or unsupported zip format. No END header found"
-};
\ No newline at end of file
diff --git a/base/util/adm-zip/util/fattr.js b/base/util/adm-zip/util/fattr.js
deleted file mode 100644
index 055cdf063..000000000
--- a/base/util/adm-zip/util/fattr.js
+++ /dev/null
@@ -1,84 +0,0 @@
-var fs = require("./fileSystem").require(),
- pth = require("path");
-
-fs.existsSync = fs.existsSync || pth.existsSync;
-
-module.exports = function(/*String*/path) {
-
- var _path = path || "",
- _permissions = 0,
- _obj = newAttr(),
- _stat = null;
-
- function newAttr() {
- return {
- directory : false,
- readonly : false,
- hidden : false,
- executable : false,
- mtime : 0,
- atime : 0
- }
- }
-
- if (_path && fs.existsSync(_path)) {
- _stat = fs.statSync(_path);
- _obj.directory = _stat.isDirectory();
- _obj.mtime = _stat.mtime;
- _obj.atime = _stat.atime;
- _obj.executable = !!(1 & parseInt ((_stat.mode & parseInt ("777", 8)).toString (8)[0]));
- _obj.readonly = !!(2 & parseInt ((_stat.mode & parseInt ("777", 8)).toString (8)[0]));
- _obj.hidden = pth.basename(_path)[0] === ".";
- } else {
- console.warn("Invalid path: " + _path)
- }
-
- return {
-
- get directory () {
- return _obj.directory;
- },
-
- get readOnly () {
- return _obj.readonly;
- },
-
- get hidden () {
- return _obj.hidden;
- },
-
- get mtime () {
- return _obj.mtime;
- },
-
- get atime () {
- return _obj.atime;
- },
-
-
- get executable () {
- return _obj.executable;
- },
-
- decodeAttributes : function(val) {
-
- },
-
- encodeAttributes : function (val) {
-
- },
-
- toString : function() {
- return '{\n' +
- '\t"path" : "' + _path + ",\n" +
- '\t"isDirectory" : ' + _obj.directory + ",\n" +
- '\t"isReadOnly" : ' + _obj.readonly + ",\n" +
- '\t"isHidden" : ' + _obj.hidden + ",\n" +
- '\t"isExecutable" : ' + _obj.executable + ",\n" +
- '\t"mTime" : ' + _obj.mtime + "\n" +
- '\t"aTime" : ' + _obj.atime + "\n" +
- '}';
- }
- }
-
-};
diff --git a/base/util/adm-zip/util/fileSystem.js b/base/util/adm-zip/util/fileSystem.js
deleted file mode 100644
index 2859791c5..000000000
--- a/base/util/adm-zip/util/fileSystem.js
+++ /dev/null
@@ -1,9 +0,0 @@
-exports.require = function() {
- var fs = require("fs");
- if (process.versions['electron']) {
- try {
- fs = require("original-fs")
- } catch (e) {}
- }
- return fs
-};
diff --git a/base/util/adm-zip/util/index.js b/base/util/adm-zip/util/index.js
deleted file mode 100644
index 870831689..000000000
--- a/base/util/adm-zip/util/index.js
+++ /dev/null
@@ -1,5 +0,0 @@
-module.exports = require("./utils");
-module.exports.FileSystem = require("./fileSystem");
-module.exports.Constants = require("./constants");
-module.exports.Errors = require("./errors");
-module.exports.FileAttr = require("./fattr");
\ No newline at end of file
diff --git a/base/util/adm-zip/util/utils.js b/base/util/adm-zip/util/utils.js
deleted file mode 100644
index df65e4f29..000000000
--- a/base/util/adm-zip/util/utils.js
+++ /dev/null
@@ -1,209 +0,0 @@
-var fs = require("./fileSystem").require(),
- pth = require('path');
-
-fs.existsSync = fs.existsSync || pth.existsSync;
-
-module.exports = (function() {
-
- var crcTable = [],
- Constants = require('./constants'),
- Errors = require('./errors'),
-
- PATH_SEPARATOR = pth.sep;
-
-
- function mkdirSync(/*String*/path) {
- var resolvedPath = path.split(PATH_SEPARATOR)[0];
- path.split(PATH_SEPARATOR).forEach(function(name) {
- if (!name || name.substr(-1,1) === ":") return;
- resolvedPath += PATH_SEPARATOR + name;
- var stat;
- try {
- stat = fs.statSync(resolvedPath);
- } catch (e) {
- fs.mkdirSync(resolvedPath);
- }
- if (stat && stat.isFile())
- throw Errors.FILE_IN_THE_WAY.replace("%s", resolvedPath);
- });
- }
-
- function findSync(/*String*/dir, /*RegExp*/pattern, /*Boolean*/recoursive) {
- if (typeof pattern === 'boolean') {
- recoursive = pattern;
- pattern = undefined;
- }
- var files = [];
- fs.readdirSync(dir).forEach(function(file) {
- var path = pth.join(dir, file);
-
- if (fs.statSync(path).isDirectory() && recoursive)
- files = files.concat(findSync(path, pattern, recoursive));
-
- if (!pattern || pattern.test(path)) {
- files.push(pth.normalize(path) + (fs.statSync(path).isDirectory() ? PATH_SEPARATOR : ""));
- }
-
- });
- return files;
- }
-
- return {
- makeDir : function(/*String*/path) {
- mkdirSync(path);
- },
-
- crc32 : function(buf) {
- if (typeof buf === 'string') {
- buf = Buffer.alloc(buf.length, buf);
- }
- var b = Buffer.alloc(4);
- if (!crcTable.length) {
- for (var n = 0; n < 256; n++) {
- var c = n;
- for (var k = 8; --k >= 0;) //
- if ((c & 1) !== 0) { c = 0xedb88320 ^ (c >>> 1); } else { c = c >>> 1; }
- if (c < 0) {
- b.writeInt32LE(c, 0);
- c = b.readUInt32LE(0);
- }
- crcTable[n] = c;
- }
- }
- var crc = 0, off = 0, len = buf.length, c1 = ~crc;
- while(--len >= 0) c1 = crcTable[(c1 ^ buf[off++]) & 0xff] ^ (c1 >>> 8);
- crc = ~c1;
- b.writeInt32LE(crc & 0xffffffff, 0);
- return b.readUInt32LE(0);
- },
-
- methodToString : function(/*Number*/method) {
- switch (method) {
- case Constants.STORED:
- return 'STORED (' + method + ')';
- case Constants.DEFLATED:
- return 'DEFLATED (' + method + ')';
- default:
- return 'UNSUPPORTED (' + method + ')';
- }
-
- },
-
- writeFileTo : function(/*String*/path, /*Buffer*/content, /*Boolean*/overwrite, /*Number*/attr) {
- if (fs.existsSync(path)) {
- if (!overwrite)
- return false; // cannot overwrite
-
- var stat = fs.statSync(path);
- if (stat.isDirectory()) {
- return false;
- }
- }
- var folder = pth.dirname(path);
- if (!fs.existsSync(folder)) {
- mkdirSync(folder);
- }
-
- var fd;
- try {
- fd = fs.openSync(path, 'w', 438); // 0666
- } catch(e) {
- fs.chmodSync(path, 438);
- fd = fs.openSync(path, 'w', 438);
- }
- if (fd) {
- try {
- fs.writeSync(fd, content, 0, content.length, 0);
- }
- catch (e){
- throw e;
- }
- finally {
- fs.closeSync(fd);
- }
- }
- fs.chmodSync(path, attr || 438);
- return true;
- },
-
- writeFileToAsync : function(/*String*/path, /*Buffer*/content, /*Boolean*/overwrite, /*Number*/attr, /*Function*/callback) {
- if(typeof attr === 'function') {
- callback = attr;
- attr = undefined;
- }
-
- fs.exists(path, function(exists) {
- if(exists && !overwrite)
- return callback(false);
-
- fs.stat(path, function(err, stat) {
- if(exists &&stat.isDirectory()) {
- return callback(false);
- }
-
- var folder = pth.dirname(path);
- fs.exists(folder, function(exists) {
- if(!exists)
- mkdirSync(folder);
-
- fs.open(path, 'w', 438, function(err, fd) {
- if(err) {
- fs.chmod(path, 438, function() {
- fs.open(path, 'w', 438, function(err, fd) {
- fs.write(fd, content, 0, content.length, 0, function() {
- fs.close(fd, function() {
- fs.chmod(path, attr || 438, function() {
- callback(true);
- })
- });
- });
- });
- })
- } else {
- if(fd) {
- fs.write(fd, content, 0, content.length, 0, function() {
- fs.close(fd, function() {
- fs.chmod(path, attr || 438, function() {
- callback(true);
- })
- });
- });
- } else {
- fs.chmod(path, attr || 438, function() {
- callback(true);
- })
- }
- }
- });
- })
- })
- })
- },
-
- findFiles : function(/*String*/path) {
- return findSync(path, true);
- },
-
- getAttributes : function(/*String*/path) {
-
- },
-
- setAttributes : function(/*String*/path) {
-
- },
-
- toBuffer : function(input) {
- if (Buffer.isBuffer(input)) {
- return input;
- } else {
- if (input.length === 0) {
- return Buffer.alloc(0)
- }
- return Buffer.alloc(input.length, input, 'utf8');
- }
- },
-
- Constants : Constants,
- Errors : Errors
- }
-})();
diff --git a/base/util/adm-zip/zipEntry.js b/base/util/adm-zip/zipEntry.js
deleted file mode 100644
index 4201e0262..000000000
--- a/base/util/adm-zip/zipEntry.js
+++ /dev/null
@@ -1,290 +0,0 @@
-var Utils = require("./util"),
- Headers = require("./headers"),
- Constants = Utils.Constants,
- Methods = require("./methods");
-
-module.exports = function (/*Buffer*/input) {
-
- var _entryHeader = new Headers.EntryHeader(),
- _entryName = Buffer.alloc(0),
- _comment = Buffer.alloc(0),
- _isDirectory = false,
- uncompressedData = null,
- _extra = Buffer.alloc(0);
-
- function getCompressedDataFromZip() {
- if (!input || !Buffer.isBuffer(input)) {
- return Buffer.alloc(0);
- }
- _entryHeader.loadDataHeaderFromBinary(input);
- return input.slice(_entryHeader.realDataOffset, _entryHeader.realDataOffset + _entryHeader.compressedSize)
- }
-
- function crc32OK(data) {
- // if bit 3 (0x08) of the general-purpose flags field is set, then the CRC-32 and file sizes are not known when the header is written
- if ((_entryHeader.flags & 0x8) !== 0x8) {
- if (Utils.crc32(data) !== _entryHeader.crc) {
- return false;
- }
- } else {
- // @TODO: load and check data descriptor header
- // The fields in the local header are filled with zero, and the CRC-32 and size are appended in a 12-byte structure
- // (optionally preceded by a 4-byte signature) immediately after the compressed data:
- }
- return true;
- }
-
- function decompress(/*Boolean*/async, /*Function*/callback, /*String*/pass) {
- if(typeof callback === 'undefined' && typeof async === 'string') {
- pass=async;
- async=void 0;
- }
- if (_isDirectory) {
- if (async && callback) {
- callback(Buffer.alloc(0), Utils.Errors.DIRECTORY_CONTENT_ERROR); //si added error.
- }
- return Buffer.alloc(0);
- }
-
- var compressedData = getCompressedDataFromZip();
-
- if (compressedData.length === 0) {
- if (async && callback) callback(compressedData, Utils.Errors.NO_DATA);//si added error.
- return compressedData;
- }
-
- var data = Buffer.alloc(_entryHeader.size);
-
- switch (_entryHeader.method) {
- case Utils.Constants.STORED:
- compressedData.copy(data);
- if (!crc32OK(data)) {
- if (async && callback) callback(data, Utils.Errors.BAD_CRC);//si added error
- return Utils.Errors.BAD_CRC;
- } else {//si added otherwise did not seem to return data.
- if (async && callback) callback(data);
- return data;
- }
- case Utils.Constants.DEFLATED:
- var inflater = new Methods.Inflater(compressedData);
- if (!async) {
- var result = inflater.inflate(data);
- result.copy(data, 0);
- if (!crc32OK(data)) {
- console.warn(Utils.Errors.BAD_CRC + " " + _entryName.toString())
- }
- return data;
- } else {
- inflater.inflateAsync(function(result) {
- result.copy(data, 0);
- if (!crc32OK(data)) {
- if (callback) callback(data, Utils.Errors.BAD_CRC); //si added error
- } else { //si added otherwise did not seem to return data.
- if (callback) callback(data);
- }
- })
- }
- break;
- default:
- if (async && callback) callback(Buffer.alloc(0), Utils.Errors.UNKNOWN_METHOD);
- return Utils.Errors.UNKNOWN_METHOD;
- }
- }
-
- function compress(/*Boolean*/async, /*Function*/callback) {
- if ((!uncompressedData || !uncompressedData.length) && Buffer.isBuffer(input)) {
- // no data set or the data wasn't changed to require recompression
- if (async && callback) callback(getCompressedDataFromZip());
- return getCompressedDataFromZip();
- }
-
- if (uncompressedData.length && !_isDirectory) {
- var compressedData;
- // Local file header
- switch (_entryHeader.method) {
- case Utils.Constants.STORED:
- _entryHeader.compressedSize = _entryHeader.size;
-
- compressedData = Buffer.alloc(uncompressedData.length);
- uncompressedData.copy(compressedData);
-
- if (async && callback) callback(compressedData);
- return compressedData;
- default:
- case Utils.Constants.DEFLATED:
-
- var deflater = new Methods.Deflater(uncompressedData);
- if (!async) {
- var deflated = deflater.deflate();
- _entryHeader.compressedSize = deflated.length;
- return deflated;
- } else {
- deflater.deflateAsync(function(data) {
- compressedData = Buffer.alloc(data.length);
- _entryHeader.compressedSize = data.length;
- data.copy(compressedData);
- callback && callback(compressedData);
- })
- }
- deflater = null;
- break;
- }
- } else {
- if (async && callback) {
- callback(Buffer.alloc(0));
- } else {
- return Buffer.alloc(0);
- }
- }
- }
-
- function readUInt64LE(buffer, offset) {
- return (buffer.readUInt32LE(offset + 4) << 4) + buffer.readUInt32LE(offset);
- }
-
- function parseExtra(data) {
- var offset = 0;
- var signature, size, part;
- while(offset= Constants.EF_ZIP64_SCOMP) {
- size = readUInt64LE(data, Constants.EF_ZIP64_SUNCOMP);
- if(_entryHeader.size === Constants.EF_ZIP64_OR_32) {
- _entryHeader.size = size;
- }
- }
- if(data.length >= Constants.EF_ZIP64_RHO) {
- compressedSize = readUInt64LE(data, Constants.EF_ZIP64_SCOMP);
- if(_entryHeader.compressedSize === Constants.EF_ZIP64_OR_32) {
- _entryHeader.compressedSize = compressedSize;
- }
- }
- if(data.length >= Constants.EF_ZIP64_DSN) {
- offset = readUInt64LE(data, Constants.EF_ZIP64_RHO);
- if(_entryHeader.offset === Constants.EF_ZIP64_OR_32) {
- _entryHeader.offset = offset;
- }
- }
- if(data.length >= Constants.EF_ZIP64_DSN+4) {
- diskNumStart = data.readUInt32LE(Constants.EF_ZIP64_DSN);
- if(_entryHeader.diskNumStart === Constants.EF_ZIP64_OR_16) {
- _entryHeader.diskNumStart = diskNumStart;
- }
- }
- }
-
-
- return {
- get entryName () { return _entryName.toString(); },
- get rawEntryName() { return _entryName; },
- set entryName (val) {
- _entryName = Utils.toBuffer(val);
- var lastChar = _entryName[_entryName.length - 1];
- _isDirectory = (lastChar === 47) || (lastChar === 92);
- _entryHeader.fileNameLength = _entryName.length;
- },
-
- get extra () { return _extra; },
- set extra (val) {
- _extra = val;
- _entryHeader.extraLength = val.length;
- parseExtra(val);
- },
-
- get comment () { return _comment.toString(); },
- set comment (val) {
- _comment = Utils.toBuffer(val);
- _entryHeader.commentLength = _comment.length;
- },
-
- get name () { var n = _entryName.toString(); return _isDirectory ? n.substr(n.length - 1).split("/").pop() : n.split("/").pop(); },
- get isDirectory () { return _isDirectory },
-
- getCompressedData : function() {
- return compress(false, null)
- },
-
- getCompressedDataAsync : function(/*Function*/callback) {
- compress(true, callback)
- },
-
- setData : function(value) {
- uncompressedData = Utils.toBuffer(value);
- if (!_isDirectory && uncompressedData.length) {
- _entryHeader.size = uncompressedData.length;
- _entryHeader.method = Utils.Constants.DEFLATED;
- _entryHeader.crc = Utils.crc32(value);
- _entryHeader.changed = true;
- } else { // folders and blank files should be stored
- _entryHeader.method = Utils.Constants.STORED;
- }
- },
-
- getData : function(pass) {
- if (_entryHeader.changed) {
- return uncompressedData;
- } else {
- return decompress(false, null, pass);
- }
- },
-
- getDataAsync : function(/*Function*/callback, pass) {
- if (_entryHeader.changed) {
- callback(uncompressedData)
- } else {
- decompress(true, callback, pass)
- }
- },
-
- set attr(attr) { _entryHeader.attr = attr; },
- get attr() { return _entryHeader.attr; },
-
- set header(/*Buffer*/data) {
- _entryHeader.loadFromBinary(data);
- },
-
- get header() {
- return _entryHeader;
- },
-
- packHeader : function() {
- var header = _entryHeader.entryHeaderToBinary();
- // add
- _entryName.copy(header, Utils.Constants.CENHDR);
- if (_entryHeader.extraLength) {
- _extra.copy(header, Utils.Constants.CENHDR + _entryName.length)
- }
- if (_entryHeader.commentLength) {
- _comment.copy(header, Utils.Constants.CENHDR + _entryName.length + _entryHeader.extraLength, _comment.length);
- }
- return header;
- },
-
- toString : function() {
- return '{\n' +
- '\t"entryName" : "' + _entryName.toString() + "\",\n" +
- '\t"name" : "' + (_isDirectory ? _entryName.toString().replace(/\/$/, '').split("/").pop() : _entryName.toString().split("/").pop()) + "\",\n" +
- '\t"comment" : "' + _comment.toString() + "\",\n" +
- '\t"isDirectory" : ' + _isDirectory + ",\n" +
- '\t"header" : ' + _entryHeader.toString().replace(/\t/mg, "\t\t").replace(/}/mg, "\t}") + ",\n" +
- '\t"compressedData" : <' + (input && input.length + " bytes buffer" || "null") + ">\n" +
- '\t"data" : <' + (uncompressedData && uncompressedData.length + " bytes buffer" || "null") + ">\n" +
- '}';
- }
- }
-};
diff --git a/base/util/adm-zip/zipFile.js b/base/util/adm-zip/zipFile.js
deleted file mode 100644
index 436baab57..000000000
--- a/base/util/adm-zip/zipFile.js
+++ /dev/null
@@ -1,320 +0,0 @@
-var ZipEntry = require("./zipEntry"),
- Headers = require("./headers"),
- Utils = require("./util");
-
-module.exports = function (/*String|Buffer*/input, /*Number*/inputType) {
- var entryList = [],
- entryTable = {},
- _comment = Buffer.alloc(0),
- filename = "",
- fs = Utils.FileSystem.require(),
- inBuffer = null,
- mainHeader = new Headers.MainHeader();
-
- if (inputType === Utils.Constants.FILE) {
- // is a filename
- filename = input;
- inBuffer = fs.readFileSync(filename);
- readMainHeader();
- } else if (inputType === Utils.Constants.BUFFER) {
- // is a memory buffer
- inBuffer = input;
- readMainHeader();
- } else {
- // none. is a new file
- }
-
- function readEntries() {
- entryTable = {};
- entryList = new Array(mainHeader.diskEntries); // total number of entries
- var index = mainHeader.offset; // offset of first CEN header
- for (var i = 0; i < entryList.length; i++) {
-
- var tmp = index,
- entry = new ZipEntry(inBuffer);
- entry.header = inBuffer.slice(tmp, tmp += Utils.Constants.CENHDR);
-
- entry.entryName = inBuffer.slice(tmp, tmp += entry.header.fileNameLength);
-
- if (entry.header.extraLength) {
- entry.extra = inBuffer.slice(tmp, tmp += entry.header.extraLength);
- }
-
- if (entry.header.commentLength)
- entry.comment = inBuffer.slice(tmp, tmp + entry.header.commentLength);
-
- index += entry.header.entryHeaderSize;
-
- entryList[i] = entry;
- entryTable[entry.entryName] = entry;
- }
- }
-
- function readMainHeader() {
- var i = inBuffer.length - Utils.Constants.ENDHDR, // END header size
- n = Math.max(0, i - 0xFFFF), // 0xFFFF is the max zip file comment length
- endOffset = -1; // Start offset of the END header
-
- for (i; i >= n; i--) {
- if (inBuffer[i] !== 0x50) continue; // quick check that the byte is 'P'
- if (inBuffer.readUInt32LE(i) === Utils.Constants.ENDSIG) { // "PK\005\006"
- endOffset = i;
- break;
- }
- }
- if (!~endOffset)
- throw Utils.Errors.INVALID_FORMAT;
-
- mainHeader.loadFromBinary(inBuffer.slice(endOffset, endOffset + Utils.Constants.ENDHDR));
- if (mainHeader.commentLength) {
- _comment = inBuffer.slice(endOffset + Utils.Constants.ENDHDR);
- }
- readEntries();
- }
-
- return {
- /**
- * Returns an array of ZipEntry objects existent in the current opened archive
- * @return Array
- */
- get entries() {
- return entryList;
- },
-
- /**
- * Archive comment
- * @return {String}
- */
- get comment() {
- return _comment.toString();
- },
- set comment(val) {
- mainHeader.commentLength = val.length;
- _comment = val;
- },
-
- /**
- * Returns a reference to the entry with the given name or null if entry is inexistent
- *
- * @param entryName
- * @return ZipEntry
- */
- getEntry: function (/*String*/entryName) {
- return entryTable[entryName] || null;
- },
-
- /**
- * Adds the given entry to the entry list
- *
- * @param entry
- */
- setEntry: function (/*ZipEntry*/entry) {
- entryList.push(entry);
- entryTable[entry.entryName] = entry;
- mainHeader.totalEntries = entryList.length;
- },
-
- /**
- * Removes the entry with the given name from the entry list.
- *
- * If the entry is a directory, then all nested files and directories will be removed
- * @param entryName
- */
- deleteEntry: function (/*String*/entryName) {
- var entry = entryTable[entryName];
- if (entry && entry.isDirectory) {
- var _self = this;
- this.getEntryChildren(entry).forEach(function (child) {
- if (child.entryName !== entryName) {
- _self.deleteEntry(child.entryName)
- }
- })
- }
- entryList.splice(entryList.indexOf(entry), 1);
- delete(entryTable[entryName]);
- mainHeader.totalEntries = entryList.length;
- },
-
- /**
- * Iterates and returns all nested files and directories of the given entry
- *
- * @param entry
- * @return Array
- */
- getEntryChildren: function (/*ZipEntry*/entry) {
- if (entry.isDirectory) {
- var list = [],
- name = entry.entryName,
- len = name.length;
-
- entryList.forEach(function (zipEntry) {
- if (zipEntry.entryName.substr(0, len) === name) {
- list.push(zipEntry);
- }
- });
- return list;
- }
- return []
- },
-
- /**
- * Returns the zip file
- *
- * @return Buffer
- */
- compressToBuffer: function () {
- if (entryList.length > 1) {
- entryList.sort(function (a, b) {
- var nameA = a.entryName.toLowerCase();
- var nameB = b.entryName.toLowerCase();
- if (nameA < nameB) {
- return -1
- }
- if (nameA > nameB) {
- return 1
- }
- return 0;
- });
- }
-
- var totalSize = 0,
- dataBlock = [],
- entryHeaders = [],
- dindex = 0;
-
- mainHeader.size = 0;
- mainHeader.offset = 0;
-
- entryList.forEach(function (entry) {
- // compress data and set local and entry header accordingly. Reason why is called first
- var compressedData = entry.getCompressedData();
- // data header
- entry.header.offset = dindex;
- var dataHeader = entry.header.dataHeaderToBinary();
- var c = entry.entryName + entry.extra.toString();
- var postHeader = Buffer.alloc(c.length, c);
- var dataLength = dataHeader.length + postHeader.length + compressedData.length;
-
- dindex += dataLength;
-
- dataBlock.push(dataHeader);
- dataBlock.push(postHeader);
- dataBlock.push(compressedData);
-
- var entryHeader = entry.packHeader();
- entryHeaders.push(entryHeader);
- mainHeader.size += entryHeader.length;
- totalSize += (dataLength + entryHeader.length);
- });
-
- totalSize += mainHeader.mainHeaderSize; // also includes zip file comment length
- // point to end of data and beginning of central directory first record
- mainHeader.offset = dindex;
-
- dindex = 0;
- var outBuffer = Buffer.alloc(totalSize);
- dataBlock.forEach(function (content) {
- content.copy(outBuffer, dindex); // write data blocks
- dindex += content.length;
- });
- entryHeaders.forEach(function (content) {
- content.copy(outBuffer, dindex); // write central directory entries
- dindex += content.length;
- });
-
- var mh = mainHeader.toBinary();
- if (_comment) {
- _comment.copy(mh, Utils.Constants.ENDHDR); // add zip file comment
- }
-
- mh.copy(outBuffer, dindex); // write main header
-
- return outBuffer
- },
-
- toAsyncBuffer: function (/*Function*/onSuccess, /*Function*/onFail, /*Function*/onItemStart, /*Function*/onItemEnd) {
- if (entryList.length > 1) {
- entryList.sort(function (a, b) {
- var nameA = a.entryName.toLowerCase();
- var nameB = b.entryName.toLowerCase();
- if (nameA > nameB) {
- return -1
- }
- if (nameA < nameB) {
- return 1
- }
- return 0;
- });
- }
-
- var totalSize = 0,
- dataBlock = [],
- entryHeaders = [],
- dindex = 0;
-
- mainHeader.size = 0;
- mainHeader.offset = 0;
-
- var compress = function (entryList) {
- var self = arguments.callee;
- if (entryList.length) {
- var entry = entryList.pop();
- var name = entry.entryName + entry.extra.toString();
- if (onItemStart) onItemStart(name);
- entry.getCompressedDataAsync(function (compressedData) {
- if (onItemEnd) onItemEnd(name);
-
- entry.header.offset = dindex;
- // data header
- var dataHeader = entry.header.dataHeaderToBinary();
- var postHeader = Buffer.alloc(name);
- var dataLength = dataHeader.length + postHeader.length + compressedData.length;
-
- dindex += dataLength;
-
- dataBlock.push(dataHeader);
- dataBlock.push(postHeader);
- dataBlock.push(compressedData);
-
- var entryHeader = entry.packHeader();
- entryHeaders.push(entryHeader);
- mainHeader.size += entryHeader.length;
- totalSize += (dataLength + entryHeader.length);
-
- if (entryList.length) {
- self(entryList);
- } else {
-
-
- totalSize += mainHeader.mainHeaderSize; // also includes zip file comment length
- // point to end of data and beginning of central directory first record
- mainHeader.offset = dindex;
-
- dindex = 0;
- var outBuffer = Buffer.alloc(totalSize);
- dataBlock.forEach(function (content) {
- content.copy(outBuffer, dindex); // write data blocks
- dindex += content.length;
- });
- entryHeaders.forEach(function (content) {
- content.copy(outBuffer, dindex); // write central directory entries
- dindex += content.length;
- });
-
- var mh = mainHeader.toBinary();
- if (_comment) {
- _comment.copy(mh, Utils.Constants.ENDHDR); // add zip file comment
- }
-
- mh.copy(outBuffer, dindex); // write main header
-
- onSuccess(outBuffer);
- }
- });
- }
- };
-
- compress(entryList);
- }
- }
-};
diff --git a/base/util/copyDirSync.js b/base/util/copyDirSync.js
index 3c0be699d..794b0ad7e 100644
--- a/base/util/copyDirSync.js
+++ b/base/util/copyDirSync.js
@@ -1,4 +1,30 @@
-function copyDirSync( source, target )
+/*
+ Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
+
+ 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.
+
+*/
+
+var fs = require("fs");
+var path = require("path");
+
+var copyDirSync = function( source, target )
{
var targetFile = target;
if ( fs.existsSync( target ) )
@@ -11,11 +37,14 @@ function copyDirSync( source, target )
fs.copyFileSync(source, targetFile);
}
-function copyFolderRecursiveSync( source, target, _root )
+var copyFolderRecursiveSync = function( source, target, _root )
{
var files = [];
var targetFolder = path.join( target, path.basename( source ) );
- if(_root) targetFolder = target;
+ if(_root)
+ {
+ targetFolder = target;
+ }
if ( !fs.existsSync( targetFolder ) )
{
fs.mkdirSync( targetFolder );
@@ -24,17 +53,18 @@ function copyFolderRecursiveSync( source, target, _root )
if ( fs.lstatSync( source ).isDirectory() )
{
files = fs.readdirSync( source );
- files.forEach( function ( file )
+ for(var i = 0; i < files.length; i++)
{
- var curSource = path.join( source, file );
+ var curSource = path.join( source, files[i] );
if ( fs.lstatSync( curSource ).isDirectory() )
{
copyFolderRecursiveSync( curSource, targetFolder );
- } else
+ }
+ else
{
copyDirSync( curSource, targetFolder );
}
- } );
+ }
}
}
diff --git a/base/util/copyRecursive.js b/base/util/copyRecursive.js
index 480b06f9e..44b794d56 100644
--- a/base/util/copyRecursive.js
+++ b/base/util/copyRecursive.js
@@ -1,3 +1,6 @@
+var fs = require("fs");
+var path = require("path");
+
var copyRecursiveSync = function(src, dest)
{
if(!fs.existsSync(src))
@@ -8,7 +11,7 @@ var copyRecursiveSync = function(src, dest)
if(fs.lstatSync( src ).isDirectory())
{
var _newDest = path.dirname(dest);
- copyDirSync(src, _newDest, true);
+ global.copyDirSync(src, _newDest, true);
}
else
{
@@ -21,7 +24,7 @@ var copyRecursiveSync = function(src, dest)
while(path.dirname(_newDest) != _newDest)
{
_newDest = path.dirname(_newDest);
- if(_newDest.indexOf(NECTAR_PATH) == 0)
+ if(_newDest.indexOf(global.NERD_PATH) == 0)
{
_path.push(_newDest);
}
diff --git a/base/util/flash.js b/base/util/flash.js
index 960c923f0..131e43a3e 100644
--- a/base/util/flash.js
+++ b/base/util/flash.js
@@ -1,58 +1,58 @@
-module.exports = Flash;
+/*
+ Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
+
+ 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.
+
+*/
var fs = require("fs");
var path = require("path");
-function Flash(from, to, target, verb)
-{
- switch(target)
- {
- case "uno":
- execFlashArduino(from, to, "ATMEGA328P", "arduino", "19200", verb)
- break;
- case "mega1280":
- execFlashArduino(from, to, "m1280", "arduino", "57600", verb)
- break;
- case "mega2560":
- execFlashArduino(from, to, "m2560", "wiring", "115200", verb)
- break;
- case "nucleo-l152re":
- case "nucleo-l432kc":
- execFlashSTM32(from, to);
- break;
- default:
- console.log("Nothing to do for target : " + target);
- break;
- }
-}
-function execFlashArduino(from, to, model, driver, bauds, verb)
+
+var execFlashArduino = function(from, to, model, driver, bauds, verb)
{
- var spawn = require('child_process').spawn;
- var _flash = spawn('avrdude', ['-p', model, "-c", driver, "-P", to, "-b", bauds, "-F", "-U", "flash:w:"+from]);
+ var spawn = require("child_process").spawn;
+ var _flash = spawn("avrdude", ["-p", model, "-c", driver, "-P", to, "-b", bauds, "-F", "-U", "flash:w:"+from]);
- _flash.stdout.on('data', function(data)
+ _flash.stdout.on("data", function(data)
{
if(verb) process.stdout.write(data.toString());
});
- _flash.stderr.on('data', function(data)
+ _flash.stderr.on("data", function(data)
{
if(verb) process.stdout.write(data.toString());
});
- _flash.on('error', function(err)
+ _flash.on("error", function(err)
{
console.log("[!] Error :");
- console.log(err)
+ console.log(err);
});
- _flash.on('close', function(code)
+ _flash.on("close", function(code)
{
- console.log("[+] Flashed")
+ console.log("[+] Flashed");
});
}
-function execFlashSTM32(from, to)
+var execFlashSTM32 = function(from, to)
{
try
{
@@ -61,7 +61,32 @@ function execFlashSTM32(from, to)
}
catch(e)
{
- console.log("[!] Your file is compiled, but an error occured while flashing, please try again.")
+ console.log("[!] Your file is compiled, but an error occured while flashing, please try again.");
}
}
+
+
+var Flash = function(from, to, target, verb)
+{
+ switch(target)
+ {
+ case "uno":
+ execFlashArduino(from, to, "ATMEGA328P", "arduino", "19200", verb);
+ break;
+ case "mega1280":
+ execFlashArduino(from, to, "m1280", "arduino", "57600", verb);
+ break;
+ case "mega2560":
+ execFlashArduino(from, to, "m2560", "wiring", "115200", verb);
+ break;
+ case "nucleo-l152re":
+ case "nucleo-l432kc":
+ execFlashSTM32(from, to);
+ break;
+ default:
+ console.log("Nothing to do for target : " + target);
+ break;
+ }
+}
+module.exports = Flash;
\ No newline at end of file
diff --git a/base/util/getExt.js b/base/util/getExt.js
index c6937cfae..834e8e3c0 100644
--- a/base/util/getExt.js
+++ b/base/util/getExt.js
@@ -1,6 +1,27 @@
-module.exports = getExt;
+/*
+ Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
-function getExt(target)
+ 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.
+
+*/
+
+var getExt = function(target)
{
switch(target)
{
@@ -39,3 +60,4 @@ function getExt(target)
break;
}
}
+module.exports = getExt;
\ No newline at end of file
diff --git a/base/util/getTips.js b/base/util/getTips.js
index b8387468d..b3407974b 100644
--- a/base/util/getTips.js
+++ b/base/util/getTips.js
@@ -1,6 +1,27 @@
-module.exports = getTips;
+/*
+ Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
-function getTips(target, file)
+ 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.
+
+*/
+
+var getTips = function(target, file)
{
switch(target)
{
@@ -8,19 +29,19 @@ function getTips(target, file)
return "";
break;
case "asm-js":
- return "[*] Tips : run this file with node : 'node " + file + "', or embed it in a .html page with "
+ return "[*] Tips : run this file with node : 'node " + file + "', or embed it in a .html page with ";
break;
case "wast":
return "";
break;
case "win-x86-32":
case "win-x86-64":
- return "[*] Tips : on Linux, you can run this .exe with Wine : 'wine " + file + "'"
+ return "[*] Tips : on Linux, you can run this .exe with Wine : 'wine " + file + "'";
break;
case "linux-x86-32":
case "linux-x86-64":
case "linux-arm32v7":
- return "[*] Tips : on Linux, don't forget to : 'chmod +x " + file + "'."
+ return "[*] Tips : on Linux, don't forget to : 'chmod +x " + file + "'.";
break;
case "arduino-uno":
return "[*] Tips : avrdude -p ATMEGA328P -c arduino -P [COMPORT] -b 19200 -F -U flash:w:" + file;
@@ -33,9 +54,11 @@ function getTips(target, file)
break;
case "nucleo-l152re":
case "nucleo-l432kc":
- return "[*] Connect your nucleo on your computer, and symple copy/paste " + file + " on the nucleo drive"
+ return "[*] Connect your nucleo on your computer, and symple copy/paste " + file + " on the nucleo drive";
default:
return "";
break;
}
}
+
+module.exports = getTips;
\ No newline at end of file
diff --git a/base/util/httpUtils.js b/base/util/httpUtils.js
deleted file mode 100644
index f3304d526..000000000
--- a/base/util/httpUtils.js
+++ /dev/null
@@ -1,79 +0,0 @@
-var http = require("http");
-var https = require("https");
-
-module.exports.httpUtil = new httpUtil(http);
-module.exports.httpsUtil = new httpUtil(https);
-
-/**
- * httpUtil Catalog of standard http call
- * @class httpUtil
- * @name httpUtil
- *
-*/
-function httpUtil(httpHandler)
-{
-
- /**
- * Send a http request.
- * @memberof httpUtil
- *
- */
- this.httpReq = function(opt, cbError, cbOk, encoding)
- {
- var data = "";
- if(opt.data) data = opt.data;
-
- if(!encoding) encoding = "utf8";
- opt.path = encodeURI(opt.path);
- var request = httpHandler.request(opt);
- request.on("error", function(err)
- {
- cbError(err);
-
- });
- request.on("response", function(response)
- {
- var data = "";
- response.on("data", function(chunk)
- {
- data += chunk.toString(encoding);
- });
- response.on("end", function()
- {
- cbOk(data);
- });
- });
- request.end(data);
- return;
- };
-
- /**
- * Send a http request and redirect output in a pipe, then call a callback when finished.
- * @memberof httpUtil
- *
- */
- this.httpReqPipe = function(opt, cbError,cbPipe, cbOk)
- {
- var data = "";
- if(opt.data) data = opt.data;
- opt.path = encodeURI(opt.path);
- var request = httpHandler.request(opt);
- request.on("error", function(err)
- {
- cbError(err);
-
- });
- request.on("response", function(response)
- {
- if(cbPipe)
- cbPipe(response);
- response.on("end", function()
- {
- if(cbOk)
- cbOk();
- });
- });
- request.end(data);
- return;
- };
-}
diff --git a/base/util/initModule.js b/base/util/initModule.js
deleted file mode 100644
index e45e70d4c..000000000
--- a/base/util/initModule.js
+++ /dev/null
@@ -1,29 +0,0 @@
-function initModule(_author, _name)
-{
- try
- {
- fs.mkdirSync("nectar_modules");
- } catch(e){}
-
- var _dest = path.join("nectar_modules", _name);
- try
- {
- fs.mkdirSync(_dest);
- }
- catch(e)
- {
- console.log("[!] An error occured while trying to create the module folder: " + _name);
- console.log(e);
- process.exit(-1);
- }
-
- var _pkg = fs.readFileSync(path.join(NECTAR_PATH, "base", "squel", "package.json")).toString();
-
- _pkg = _pkg.replace(/{{AUTHOR}}/g, _author).replace(/{{MODULE_NAME}}/g, _name)
-
- fs.writeFileSync(path.join(_dest, "package.json"), _pkg);
- fs.appendFileSync(path.join(_dest, "index.js"), "// Write your module code here");
- console.log("[+] Module " + _name + " correctly initialized in " + _dest);
-}
-
-module.exports = initModule;
\ No newline at end of file
diff --git a/base/util/installModule.js b/base/util/installModule.js
deleted file mode 100644
index 31d32e10a..000000000
--- a/base/util/installModule.js
+++ /dev/null
@@ -1,49 +0,0 @@
-function installModule(_name)
-{
- try
- {
- fs.mkdirSync("nectar_modules");
- }catch(e){}
-
- try
- {
- fs.mkdirSync(".nectar");
- }catch(e){}
-
- var _zip = _name + ".zip"
- var _tmp = path.join(".nectar", _zip);
- var _dest = path.join("nectar_modules");
-
- const file = fs.createWriteStream(_tmp);
-
- var opt =
- {
- "host": "modules.nectarjs.org",
- "path": "/" + _zip,
- }
-
- function onError(_err)
- {
- console.log(_err);
- console.log("[!] Module " + _name + " does not exist");
- }
-
- function pipe(_res)
- {
- _res.pipe(file);
- }
-
- function onSuccess()
- {
- var unzip = new Zip(_tmp);
- unzip.extractAllTo(_dest, true);
- rmdir(_tmp, function()
- {
- console.log("[+] Module " + _name + " installed");
- });
- }
-
- coreHttp.httpsUtil.httpReqPipe(opt, onError, pipe, onSuccess);
-}
-
-module.exports = installModule;
\ No newline at end of file
diff --git a/base/util/lint.js b/base/util/lint.js
deleted file mode 100644
index 9f33777e9..000000000
--- a/base/util/lint.js
+++ /dev/null
@@ -1,52 +0,0 @@
-var Linter = require("eslint").Linter;
-var linter = new Linter();
-
-function nectarLint(_code, _file, _expose)
-{
- var _fatal = false;
-
- if(!COMPILER.ENV.check.globals) COMPILER.ENV.check.globals = {};
-
- if(_expose)
- {
- for(var i = 0; i < _expose.length; i++)
- {
- COMPILER.ENV.check.globals[_expose[i]] = false;
- }
- }
-
- if(CLI.cli["--no-undef-error"])
- {
- COMPILER.ENV.check.rules["no-undef"] = "error";
- }
-
- if(CLI.cli["--no-undef-warn"])
- {
- COMPILER.ENV.check.rules["no-undef"] = "warn";
- }
-
- if(CLI.cli["--no-semi-error"])
- {
- COMPILER.ENV.check.rules["semi"] = ["error", "always"];
- }
-
- if(CLI.cli["--no-semi-warn"])
- {
- COMPILER.ENV.check.rules["semi"] = ["warn", "always"];
- }
-
-
- var _res = linter.verify(_code, COMPILER.ENV.check, { filename: _file });
- for(var i = 0; i < _res.length; i++)
- {
- if(_res[i].severity > 1)
- {
- _fatal = true;
- console.log("[error]", _res[i].message, "line", _res[i].line, "column", _res[i].column, "in file", _file);
- }
- else console.log("[warning]", _res[i].message, "line", _res[i].line, "column", _res[i].column, "in file", _file);
- }
- if(_fatal) process.exit(1);
-}
-
-module.exports = nectarLint;
diff --git a/base/util/rmdir.js b/base/util/rmdir.js
deleted file mode 100644
index 6c0ee8cd8..000000000
--- a/base/util/rmdir.js
+++ /dev/null
@@ -1,79 +0,0 @@
-var rmdir = function(dir, callback)
-{
- fs.readdir(dir, function(err, list)
- {
- if(err)
- {
- try
- {
- fs.unlink(dir, function(err)
- {
- callback(err);
- });
- }
- catch(e){}
- }
- else
- {
- var i = 0;
- var j = list.length;
- var cb = function(){ fs.rmdir(dir, function(err){if(callback && typeof callback == "function") callback(err);});};
- recursiveRm(dir, i, j, list, cb);
- return;
- }
- });
-
- function recursiveRm(from, i, j, list, cb)
- {
-
- function nextFile()
- {
- i++;
- if(i < j)
- {
- recursiveRm(from, i, j, list, cb);
- }
- else
- {
- if(cb && typeof cb == "function")
- cb();
- }
- }
- var filename = "";
-
- try
- {
- filename = path.join(from, list[i]);
- }
- catch(e)
- {
- nextFile();
- return;
- }
-
- fs.stat(filename, function(err, stat)
- {
- if(err)
- {
- nextFile();
- }
- else if(stat.isDirectory())
- {
- if(filename)
- {
- rmdir(filename, nextFile);
- }
- else
- {
- nextFile();
- }
- }
- else
- {
- fs.unlink(filename, nextFile);
- }
- });
- }
-};
-
-module.exports = rmdir;
\ No newline at end of file
diff --git a/compiler/native/compiler.js b/compiler/native/compiler.js
index 777aa7ef8..8d83b5ef9 100644
--- a/compiler/native/compiler.js
+++ b/compiler/native/compiler.js
@@ -1,43 +1,25 @@
/*
- * This file is part of NectarJS
- * Copyright (c) 2017 - 2020 Adrien THIERRY
- * http://nectarjs.com - https://seraum.com/
- *
- * sources : https://github.com/nectarjs/nectarjs
- *
- * NectarJS is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * NectarJS is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with NectarJS. If not, see .
- *
- */
-
-global.strip = require("strip-comments");
-global.babel = require( '@babel/core' );
-babel.generate = require( '@babel/generator' ).default;
+ Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
- var visitor = require("./visitor/visitor.js");
-
-var genRequire = require("./lib/genRequire.js");
-global.genMetaFunction = require("./lib/genMetaFunction.js");
-global.genPackage = require("./lib/genPackage.js");
-global.replaceObjAddr = require("./lib/replaceObjAddr.js");
+ 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:
-var createFunction = require("./lib/createFunction.js");
-var createAnon = require("./lib/createAnon.js");
-var createReturnAnon = require("./lib/createReturnAnon.js");
-var createClass = require("./lib/createClass.js");
-var hoistingFunction = require("./lib/hoistingFunction.js");
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
-global.RND = function() { return "__" + Math.random().toString(36).substring(7); };
+ 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.
+
+*/
global.ENV = loadEnv();
function loadEnv()
@@ -54,45 +36,6 @@ function loadEnv()
return _res;
}
-function setRegister(_value)
-{
- try
- {
- COMPILER.REGISTER = parseInt(_value)
- console.log("[*] Set register at: " + COMPILER.REGISTER);
- }
- catch(e)
- {
- console.log("[!] Invalid register, integer needed");
- process.exit(1);
- }
-}
-
-var FAST_CALL = ["BinaryExpression", "NumericLiteral"];
-function checkFastFunction()
-{
- for(var i in COMPILER.INFO.SCOPE)
- {
- for(var j = 0; j < COMPILER.INFO.SCOPE[i].use.length; j++)
- {
- if(COMPILER.INFO.SCOPE[i].init.indexOf(COMPILER.INFO.SCOPE[i].use[j]) < 0)
- {
- COMPILER.INFO.SCOPE[i].fast = false;
- break;
- }
- }
-
- for(var j = 0; j < COMPILER.INFO.SCOPE[i].call.length; j++)
- {
- if(FAST_CALL.indexOf(COMPILER.INFO.SCOPE[i].call[j]) < 0)
- {
- COMPILER.INFO.SCOPE[i].fast = false;
- break;
- }
- }
- }
-}
-
function Compiler()
{
var _handler = this;
@@ -106,6 +49,7 @@ function Compiler()
this.LIBS = "";
this.STATE = "";
this.PACK = [];
+ this.DIR = [];
if(CLI.stack[0]) this.PATH = path.dirname(CLI.stack[0]) + path.sep;
@@ -132,31 +76,21 @@ function Compiler()
this.OUT = "";
this.TMP_FOLDER = "";
this.OPTION = "";
- this.REGISTER = 100000;
-
- this.DECL = [];
-
- this.FFI = [];
-
+
this.INIT = "";
-
+ this.DECL = "";
this.REQUIRE = "";
-
- this.READ_ONLY = [];
+ this.INCLUDE = "";
this.INFO =
{
- Function: [],
+ FUNCTION: [],
CACHE: {},
VALUE: [],
CALL: {},
SCOPE: {},
HOISTING: [],
};
-
- this.GLOBAL = ["__NJS_THIS", "parseInt", "setImmediate", "setTimeout", "setInterval"];
-
- this.VAR_STATE = [[]];
if(this.ENV.stdlib)
{
@@ -164,94 +98,41 @@ function Compiler()
{
if(typeof this.ENV.stdlib[_s] == "string")
{
- this.DECL.push("var " + this.ENV.stdlib[_s] + ";");
+ this.DECL += "var " + this.ENV.stdlib[_s] + ";";
this.STD += this.ENV.stdlib[_s] + " = require(\"" + this.ENV.stdlib[_s] + "\");";
}
else if(typeof this.ENV.stdlib[_s] == "object")
{
- this.DECL.push("var " + this.ENV.stdlib[_s].bind + ";");
+ this.DECL += "var " + this.ENV.stdlib[_s].bind + ";";
this.STD += this.ENV.stdlib[_s].bind + " = require(\"" + this.ENV.stdlib[_s].module + "\");";
}
}
}
- if(this.ENV.check && this.ENV.check.globals)
- {
- for(var g in this.ENV.check.globals)
- {
- this.VAR_STATE[0].push(g);
- }
- }
this.CODE = "";
this.FOOTER = "";
/*** METHODS ***/
- this.Parse = function(_code)
+ this.Parse = function(code, _file)
{
- _code = strip(_code);
- if(CLI.cli["--preset"] && CLI.cli["--preset"].argument == "speed")
- {
- _code = babel.transformSync(_code,
- {
- plugins: [path.join(NECTAR_PATH, "node_modules", "babel-plugin-remove-unused-vars"),
- path.join(NECTAR_PATH, "node_modules", "babel-plugin-minify-dead-code-elimination"),
- path.join(NECTAR_PATH, "node_modules", "babel-plugin-minify-guarded-expressions")],
- }).code;
- }
-
- if(!CLI.cli["--no-check"]) LINT(_code, this.IN);
-
-
-
- _code = genRequire(_handler.PATH, COMPILER.STD) + genRequire(_handler.PATH, _code);
-
- COMPILER.STATE = "REQUIRE";
- COMPILER.REQUIRE = babel.transformSync(COMPILER.REQUIRE, visitor).code;
- checkFastFunction();
- COMPILER.REQUIRE = createClass(COMPILER.REQUIRE);
- COMPILER.REQUIRE = createFunction(COMPILER.REQUIRE);
- COMPILER.REQUIRE = createAnon(COMPILER.REQUIRE);
- COMPILER.REQUIRE = createReturnAnon(COMPILER.REQUIRE);
-
- COMPILER.STATE = "CODE";
-
- _handler.CODE = babel.transformSync(_code, visitor).code;
- _code = hoistingFunction(_code);
- checkFastFunction();
- _handler.CODE = createClass(_handler.CODE, true);
-
- _handler.CODE = createFunction(_handler.CODE, true);
- _handler.CODE = createAnon(_handler.CODE, true);
- _handler.CODE = createReturnAnon(_handler.CODE, true);
-
- var _hoisting = "";
- for(var i = 0; i < COMPILER.INFO.HOISTING.length; i++)
- {
- _hoisting += "var " + COMPILER.INFO.HOISTING[i] + ";";
- }
- _handler.CODE = _handler.CODE;
-
- COMPILER.INIT += COMPILER.REQUIRE + _hoisting;
-
- _handler.DECL = _handler.DECL.filter(function(v,i)
- {
- return _handler.DECL.indexOf(v) === i;
- }).join(";");
-
- _handler.MAIN = _handler.MAIN.replace("{CODE}", _handler.CODE);
- _handler.MAIN = _handler.MAIN.replace("{INIT}", _handler.INIT);
- _handler.MAIN = _handler.MAIN.replace("{DECL}", _handler.DECL);
- _handler.MAIN = _handler.MAIN.replace("{INCLUDE}", _handler.FFI.join(os.EOL));
+ var _env = createEnv(_handler.PATH, _file);
+ code = this.STD + code;
+ parseCode(code, 0, _env);
+ parseAST(_env);
+ var _generated = generateCode(_env);
+ _handler.MAIN = _handler.MAIN.replace("{CODE}", _generated);
+ _handler.MAIN = _handler.MAIN.replace("{INIT}", COMPILER.INIT);
+ _handler.MAIN = _handler.MAIN.replace("{DECL}", COMPILER.DECL);
+ _handler.MAIN = _handler.MAIN.replace("{INCLUDE}", COMPILER.INCLUDE);
_handler.MAIN = _handler.MAIN.replace("{{__PLATFORM__}}", os.platform());
-
}
this.Prepare = function(_folder)
{
if((!CLI.cli["--profile"]) || CLI.cli["--profile"].argument != "use")
{
- copyDirSync(path.join(__dirname, "nectarcpp", "src"), _folder, true);
+ copyDirSync(path.join(__dirname, "nerdcore"), _folder, false);
}
};
@@ -273,6 +154,8 @@ function Compiler()
this.Compile = function(_folder, _file)
{
+
+ fs.writeFileSync(_file, _handler.MAIN);
process.chdir(_folder);
var _exec = _handler.CLI(_handler.COMPILER, _handler.OUT, _file, _handler.OPTION);
execSync(_exec);
diff --git a/compiler/native/env/android.js b/compiler/native/env/android.js
deleted file mode 100644
index 4da81c09e..000000000
--- a/compiler/native/env/android.js
+++ /dev/null
@@ -1,109 +0,0 @@
-var os = require("os");
-
-var ANDROID =
-{
- name: "android",
- main: "android.cpp",
- compiler: "gradlew",
- stdlib: [{bind: "Nectar", module: "android"}, "Object", "Math", "JSON"],
- check:
- {
- "env":
- {
- "es6": true
- },
- "extends": "eslint:recommended",
- "rules":
- {
- "strict": "global",
- "no-console": "off",
- "indent": "off",
- "linebreak-style": "off",
- "no-unused-vars": ["warn", { "vars": "all", "args": "after-used", "ignoreRestSiblings": false }],
- "no-const-assign": "error",
- },
- "globals":
- {
- "undefined": false,
- "eval": false,
- "__njs_typeof": false,
- "console": false,
- "module": false,
- "require": false,
- "__Nectar_Log_Console": false,
- "__Nectar_InitVar": false,
- "__Nectar_Object_Keys": false,
- "__Nectar_Object_Stringify": false,
- "__Nectar_Call_Function": false,
- "__NJS_ARGS": false,
- "__NJS_ENV": false,
- "__NJS_PLATFORM": false,
- "__Nectar_typeof": false,
- "__Nectar_THIS": false,
- "__Nectar_instanceof": false,
- "__Nectar_delete": false,
- "JSON": false,
- "Object": false,
- "isNaN": false,
- "Array": false,
- },
- },
- cli: function(compiler, preset, out, _in, option)
- {
-
- var _pre = "./";
- if(os.platform() == "win32") _pre = "";
- var apkOut = "";
-
- if(CLI.cli["--target"] && CLI.cli["--target"].argument)
- {
- if(CLI.cli["--target"].argument == "release")
- {
- apkOut = path.join(COMPILER.TMP_FOLDER, "app", "build", "outputs", "apk", "release", "app-release-unsigned.apk");
- }
- else if(CLI.cli["--target"].argument == "debug")
- {
- apkOut = path.join(COMPILER.TMP_FOLDER, "app", "build", "outputs", "apk", "debug", "app-debug.apk");
- }
- else
- {
- console.log("[!] Error: accepted target are: debug or release");
- }
-
- }
- else
- {
- apkOut = path.join(COMPILER.TMP_FOLDER, "app", "build", "outputs", "apk", "debug", "app-debug.apk");
- }
-
- return `${_pre}${compiler} build && cp ${apkOut} ${out}`;
- },
- out: function(_name)
- {
- return _name + ".apk";
- },
- init: function(_folder)
- {
- copyDirSync(path.join(COMPILER.MAIN_PATH, "platform", "android"), _folder, true);
- },
- prepare: function(_folder)
- {
- var _www = path.join(path.resolve(path.dirname(COMPILER.IN)), "www");
- if(fs.existsSync(_www))
- {
- copyDirSync(_www, path.join(_folder, "app", "src", "main", "assets", "raw"), true);
- }
- var _name = path.basename(COMPILER.IN).split(".")[0];
- fs.writeFileSync(path.join(_folder, "local.properties"), `ndk.dir=${CONFIG.ndk}\nsdk.dir=${CONFIG.sdk}\ngradle=build -x lint -x lintVitalRelease\n`);
- fs.writeFileSync(path.join(_folder, "settings.gradle"), `rootProject.name='nectar_android_app'\ninclude ':app'\n`);
-
- return path.join(_folder, "app", "src", "main", "cpp");
- },
- write: function(_content)
- {
- fs.writeFileSync(path.join(COMPILER.TMP_FOLDER, "app", "src", "main", "cpp", "native-lib.cpp"), _content);
- }
-
-}
-
-module.exports = ANDROID;
diff --git a/compiler/native/env/arduino.js b/compiler/native/env/arduino.js
index 2200e95bf..c4136195b 100644
--- a/compiler/native/env/arduino.js
+++ b/compiler/native/env/arduino.js
@@ -41,14 +41,15 @@ var ARDUINO =
if(!target || !OPTIONS[target])
{
- console.log("[!] No target selected, switching to 'uno'");
+ console.log("[!] No target or bad target selected, switching to 'uno'");
target = "uno";
}
- var _cli = `${compiler} ${OPTIONS[target].preset} -D__Nectar__OBJECT_VECTOR -DARDUINO_ARCH_AVR -w -Os -fno-exceptions -fno-rtti -fno-stack-protector -fomit-frame-pointer -ffunction-sections -fdata-sections -Wl,--gc-sections \
- -I ${extern}/avr -I ${extern}/arduino/avr/variants/${OPTIONS[target].variant}/ -I ${extern}/arduino/avr/cores/arduino -I ${extern}/avr/include -I ${extern}/stlarduino ${extern}/stlarduino/ios.cpp ${extern}/arduino/avr/cores/arduino/abi.cpp -fno-threadsafe-statics -lm ${COMPILER.LIBS} -o ${out} ${_in} ${_cliOption}`;
+ var _cli = `${compiler} ${OPTIONS[target].preset} -D__NERD__OBJECT_VECTOR -DARDUINO_ARCH_AVR -w -Os -fno-exceptions -fno-rtti -fno-stack-protector -fomit-frame-pointer -ffunction-sections -fdata-sections -Wl,--gc-sections \
+ -I ${extern}/arduino/avr -I ${extern}/arduino/avr/variants/${OPTIONS[target].variant}/ -I ${extern}/arduino/avr/cores/arduino -I ${extern}/arduino/stlarduino ${extern}/arduino/stlarduino/ios.cpp ${extern}/arduino/avr/cores/arduino/abi.cpp ${extern}/arduino/stlarduino/new*.cpp ${extern}/arduino/stlarduino/char_traits.cpp ${extern}/arduino/stlarduino/del*.cpp ${extern}/arduino/stlarduino/stdexcept.cpp ${extern}/arduino/stlarduino/func_exception.cpp ${extern}/arduino/stlarduino/ostream_helpers.cpp -fno-threadsafe-statics -lm ${COMPILER.LIBS} -o ${out} ${_in} ${_cliOption}`;
if(!OPT.elf) _cli += `&& avr-objcopy -O ihex -R .eeprom ${out}`;
if(OPT.cli) console.log("[*]" + _cli);
+
return _cli;
},
compiler: "avr-g++ -std=c++17",
@@ -60,47 +61,7 @@ var ARDUINO =
else _name += ".hex";
return _name;
},
- check: {
- "env": {
- "es6": true
- },
- "extends": "eslint:recommended",
- "rules": {
- "global-require": "error",
- "no-console": "error",
- "indent": "off",
- "linebreak-style": "off",
- "no-unused-vars": ["warn", { "vars": "all", "args": "after-used", "varsIgnorePattern": "setup|loop", "ignoreRestSiblings": false }],
- "no-const-assign": "error",
- },
- "globals":
- {
- "undefined": false,
- "eval": false,
- "__njs_typeof": false,
- "console": false,
- "module": false,
- "require": false,
- "__Nectar_Log_Console": false,
- "__Nectar_InitVar": false,
- "__Nectar_Object_Keys": false,
- "__Nectar_Object_Stringify": false,
- "__Nectar_Call_Function": false,
- "__NJS_ARGS": false,
- "__NJS_ENV": false,
- "__NJS_PLATFORM": false,
- "__Nectar_typeof": false,
- "__Nectar_THIS": false,
- "__Nectar_instanceof": false,
- "__Nectar_delete": false,
- "__Nectar_EQUAL_VALUE_AND_TYPE": false,
- "__Nectar_NOT_EQUAL_VALUE_AND_TYPE": false,
- "JSON": false,
- "Object": false,
- "isNaN": false,
- "Array": false,
- }
- }
+
}
-module.exports = ARDUINO;
+module.exports = ARDUINO;
\ No newline at end of file
diff --git a/compiler/native/env/esp32.js b/compiler/native/env/esp32.js
deleted file mode 100644
index f89562b75..000000000
--- a/compiler/native/env/esp32.js
+++ /dev/null
@@ -1,73 +0,0 @@
-var os = require("os");
-
-var ESP32 =
-{
- name: "esp32",
- main: "esp32.cpp",
- compiler: "idf.py",
- stdlib: [],
- check:
- {
- "env":
- {
- "es6": true
- },
- "extends": "eslint:recommended",
- "rules":
- {
- "strict": "global",
- "no-console": "off",
- "indent": "off",
- "linebreak-style": "off",
- "no-unused-vars": ["warn", { "vars": "all", "args": "after-used", "ignoreRestSiblings": false }],
- "no-const-assign": "error",
- },
- "globals":
- {
- "undefined": false,
- "eval": false,
- "__njs_typeof": false,
- "console": false,
- "module": false,
- "require": false,
- "__Nectar_Log_Console": false,
- "__Nectar_InitVar": false,
- "__Nectar_Object_Keys": false,
- "__Nectar_Object_Stringify": false,
- "__Nectar_Call_Function": false,
- "__NJS_ARGS": false,
- "__NJS_ENV": false,
- "__NJS_PLATFORM": false,
- "__Nectar_typeof": false,
- "__Nectar_THIS": false,
- "__Nectar_instanceof": false,
- "__Nectar_delete": false,
- "__Nectar_EQUAL_VALUE_AND_TYPE": false,
- "__Nectar_NOT_EQUAL_VALUE_AND_TYPE": false,
- "JSON": false,
- "Object": false,
- "isNaN": false,
- "Array": false,
- },
- },
- cli: function(compiler, preset, out, _in, option)
- {
- var bin = path.join(COMPILER.TMP_FOLDER, "build", "njs.bin");
- return `${compiler} build && cp ${bin} ${out}`;
- },
- out: function(_name)
- {
- return _name + ".bin";
- },
- init: function(_folder)
- {
- copyDirSync(path.join(COMPILER.MAIN_PATH, "platform", "esp32"), _folder, true);
- },
- write: function(_content)
- {
- fs.writeFileSync(path.join(COMPILER.TMP_FOLDER, "esp32.cpp"), _content);
- }
-
-}
-
-module.exports = ESP32;
diff --git a/compiler/native/env/ios.js b/compiler/native/env/ios.js
deleted file mode 100644
index 271988ff5..000000000
--- a/compiler/native/env/ios.js
+++ /dev/null
@@ -1,115 +0,0 @@
-var os = require("os");
-
-var IOS =
-{
- name: "ios",
- main: "ios.hpp",
- compiler: "xcodebuild",
- stdlib: [{bind: "Nectar", module: "iOS"}, "console", "Object", "Math", "JSON" ],
- check:
- {
- "env":
- {
- "es6": true
- },
- "extends": "eslint:recommended",
- "rules":
- {
- "strict": "global",
- "no-console": "off",
- "indent": "off",
- "linebreak-style": "off",
- "no-unused-vars": ["warn", { "vars": "all", "args": "after-used", "ignoreRestSiblings": false }],
- "no-const-assign": "error",
- },
- "globals":
- {
- "undefined": false,
- "eval": false,
- "__njs_typeof": false,
- "console": false,
- "module": false,
- "require": false,
- "__Nectar_Log_Console": false,
- "__Nectar_InitVar": false,
- "__Nectar_Object_Keys": false,
- "__Nectar_Object_Stringify": false,
- "__Nectar_Call_Function": false,
- "__NJS_ARGS": false,
- "__NJS_ENV": false,
- "__NJS_PLATFORM": false,
- "__Nectar_typeof": false,
- "__Nectar_THIS": false,
- "__Nectar_instanceof": false,
- "__Nectar_delete": false,
- "__Nectar_EQUAL_VALUE_AND_TYPE": false,
- "__Nectar_NOT_EQUAL_VALUE_AND_TYPE": false,
- "JSON": false,
- "Object": false,
- "isNaN": false,
- "Array": false,
- },
- },
- out: function(_name)
- {
- return _name + ".app";
- },
- init: function(_folder)
- {
- copyDirSync(path.join(COMPILER.MAIN_PATH, "platform", "ios"), _folder, true);
- },
- write: function(code)
- {
- fs.writeFileSync(path.join(COMPILER.TMP_FOLDER, "ios.hpp"), code);
- },
- post: function()
- {
- try
- {
- fs.mkdirSync(COMPILER.OUT);
- }
- catch(e){}
- copyDirSync (`${COMPILER.TMP_FOLDER}/build/NectarIOS.app`, COMPILER.OUT, true);
- },
- run: function()
- {
- var device;
- if(CLI.cli["--target"]) device = '--devicetypeid \'' + CLI.cli["--target"].argument + '\'';
- else
- {
- console.log('Please, specify a target with --run on ios env');
- process.exit(1);
- }
- var runit = 'ios-sim launch ' + COMPILER.OUT + ' ' + device ;
-
- try
- {
- child_process.execSync(runit);
- }
- catch(e){}
- },
- prepare: function(_folder)
- {
- var _www = path.join(path.resolve(path.dirname(COMPILER.IN)), "www");
- if(fs.existsSync(_www))
- {
- copyDirSync(_www, path.join(_folder, "NectarIOS", "raw"), true);
- }
-
- return path.join(_folder, "NectarIOS");
- },
- cli: function(compiler, preset, out, _in, option)
- {
- var device = '';
- if(CLI.cli["--target"])
- {
- var info = CLI.cli["--target"].argument.split(", ");
- device = '-destination \'platform=iOS Simulator,name=' + info[0].split("-").join(" ") + ',OS=' + info[1] + '\'';
- }
- else device = '-destination generic/platform=iOS';
- return `${compiler} build -scheme NectarIOS ${device} CONFIGURATION_BUILD_DIR="${COMPILER.TMP_FOLDER}/build/" CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO CODE_SIGN_ENTITLEMENTS="" CODE_SIGNING_ALLOWED="NO"`;
- }
-
-}
-
-module.exports = IOS;
diff --git a/compiler/native/env/js.js b/compiler/native/env/js.js
new file mode 100644
index 000000000..262d6b800
--- /dev/null
+++ b/compiler/native/env/js.js
@@ -0,0 +1,141 @@
+/*
+ Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
+
+ 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.
+
+*/
+var _debug = " -g ";
+var JS =
+{
+ name: "js",
+ main: "js.cpp",
+ compiler: "g++",
+ stdlib: ["console", "JSON", "Module", "process", "RegExp", "Math"],
+ cli: function(compiler, preset, out, _in, option)
+ {
+ var _cachePath = path.join(process.cwd(), "..", "cached_" + COMPILER.ENV.name + "_" + os.platform + "_" + VERSION);
+ var _precompiled = path.join(_cachePath, "nerd.o");
+
+ var _stack = 0;
+ if(CLI.cli["--stack"])
+ {
+ try
+ {
+ _stack = parseInt(CLI.cli["--stack"].argument);
+ }
+ catch(e)
+ {
+ console.log("[!] Error: --stack flags required a number, received -> " + CLI.cli["--stack"].argument);
+ process.exit(1);
+ }
+ }
+
+ if(!fs.existsSync(_precompiled))
+ {
+
+ var _args = " -flto -Ofast ";
+ if(preset == "debug")
+ {
+ console.log("Building core with debug");
+ _args = _debug;
+ }
+
+ console.log(`[+] Creating Nerd binary lib for ${COMPILER.ENV.name + "_" + os.platform + "_" + VERSION}`);
+ console.log(`${compiler} -std=c++17 ${_args} -c nerdcore/src/nerd.cpp -o "${_precompiled}"`);
+ try { fs.mkdirSync(_cachePath); } catch(e){};
+ execSync(`${compiler} -std=c++17 ${_args} -c nerdcore/src/nerd.cpp -o "${_precompiled}"`);
+ console.log("[+] Compiling with precompiled Nerd lib");
+ }
+
+ if(compiler == "cl" || compiler.indexOf("cl ") == 0)
+ {
+ console.log("[!] cl is not supported, please use g++, clang++, em++ or avr-g++");
+ process.exit(1);
+ }
+
+ var _hashmap = "";
+ if(CLI.cli['--no-object-hashmap']) _hashmap = "-D__NERD__OBJECT_VECTOR";
+
+ if(_stack) _stack = "-Wl,--stack," + _stack;
+ else _stack = "";
+
+ var _sysVNetLibs = "";
+ if(os.platform() == "sunos") _sysVNetLibs = "-lsocket -lnsl";
+
+ var _cliOption = "";
+ if(CLI.cli["--option"]) _cliOption = CLI.cli["--option"].argument;
+
+
+ if(CLI.cli["--profile"])
+ {
+ if(!CLI.cli["--conserve"]) CLI.cli["--conserve"] = true;
+ if(CLI.cli["--profile"].argument == "gen")
+ {
+ _cliOption += " -fprofile-generate";
+ console.log("[*] Profiling data will be stored in: " + COMPILER.TMP_FOLDER);
+ }
+ else if(CLI.cli["--profile"].argument == "use")
+ {
+ _cliOption += " -fprofile-use";
+ console.log("[*] Using profile data from: " + COMPILER.TMP_FOLDER);
+ }
+ else
+ {
+ console.log("[!] Please use --profile with gen or use");
+ }
+ }
+
+ var _files = `"${_precompiled}" "${_in}"`;
+ if(os.platform == "win32") _files = `"${_in}" "${_precompiled}"`;
+
+ if(preset == "none")
+ {
+ return `${compiler} ${_stack} -std=c++17 ${_files} -g -s ${COMPILER.LIBS} -pthread -o "${out}" ${_sysVNetLibs} ${_cliOption}`;
+ }
+ else if(preset == "debug")
+ {
+ console.log(`${compiler} ${_stack} -std=c++17 ${_files} ${_debug} -s ${COMPILER.LIBS} -pthread -o "${out}" ${_sysVNetLibs} ${_cliOption}`);
+ return `${compiler} ${_stack} -std=c++17 ${_files} ${_debug} -s ${COMPILER.LIBS} -pthread -o "${out}" ${_sysVNetLibs} ${_cliOption}`;
+ }
+ else if(preset == "size")
+ {
+ return `${compiler} ${_stack} -std=c++17 ${_files} -pthread -Os -fno-rtti -fno-stack-protector -fomit-frame-pointer -s ${COMPILER.LIBS} -o "${out}" ${_sysVNetLibs} ${_cliOption}`;
+ }
+ else
+ {
+ var _opt = "-O";
+ if(os.platform() == "darwin" || compiler.indexOf("clang") > -1) _opt += "3";
+ else _opt += "fast";
+ _opt += " -flto";
+ return `${compiler} ${_stack} -std=c++17 ${_files} ${_opt} -pthread -s ${COMPILER.LIBS} -o "${out}" ${_sysVNetLibs} ${_cliOption}`;
+ }
+ },
+ write: function(_content, _in)
+ {
+ if(CLI.cli["--profile"] && CLI.cli["--profile"].argument == "use")
+ {
+ return;
+ }
+
+ fs.writeFileSync(_in, _content);
+ }
+
+}
+
+module.exports = JS;
diff --git a/compiler/native/env/node.js b/compiler/native/env/node.js
deleted file mode 100644
index e909dfcbb..000000000
--- a/compiler/native/env/node.js
+++ /dev/null
@@ -1,123 +0,0 @@
-var NODE =
-{
- name: "node",
- main: "node.cpp",
- compiler: "g++",
- stdlib: ["console", "Object", "Math", "JSON"],
- check: {
- "env": {
- "node": true,
- "es6": true
- },
- "extends": "eslint:recommended",
- "rules": {
- "no-console": "off",
- "indent": "off",
- "linebreak-style": "off",
- "no-unused-vars": ["warn", { "vars": "all", "args": "after-used", "ignoreRestSiblings": false }],
- "no-const-assign": "error",
- },
- "globals":
- {
- "undefined": false,
- "eval": false,
- "__njs_typeof": false,
- "console": false,
- "module": false,
- "require": false,
- "__Nectar_Log_Console": false,
- "__Nectar_InitVar": false,
- "__Nectar_Object_Keys": false,
- "__Nectar_Object_Stringify": false,
- "__Nectar_Call_Function": false,
- "__NJS_ARGS": false,
- "__NJS_ENV": false,
- "__NJS_PLATFORM": false,
- "__Nectar_typeof": false,
- "__Nectar_THIS": false,
- "__Nectar_instanceof": false,
- "__Nectar_delete": false,
- "__Nectar_EQUAL_VALUE_AND_TYPE": false,
- "__Nectar_NOT_EQUAL_VALUE_AND_TYPE": false,
- "JSON": false,
- "Object": false,
- "isNaN": false,
- "Array": false,
- }
- },
- cli: function(compiler, preset, out, _in, option)
- {
- var _cachePath = path.join(process.cwd(), "..", "cached_" + COMPILER.ENV.name + "_" + os.platform + "_" + VERSION);
- var _precompiled = path.join(_cachePath, "nectar.o");
-
- var _stack = 0;
-
- if(CLI.cli["--stack"])
- {
- try
- {
- _stack = parseInt(CLI.cli["--stack"].argument);
- }
- catch(e)
- {
- console.log("[!] Error: --stack flags required a number, received -> " + CLI.cli["--stack"].argument);
- process.exit(1);
- }
- }
-
- if(!fs.existsSync(_precompiled))
- {
- console.log(`[+] Creating Nectar binary lib for ${COMPILER.ENV.name + "_" + os.platform + "_" + VERSION}`);
- try { fs.mkdirSync(_cachePath); } catch(e){};
- execSync(`${compiler} -std=c++17 -c nectar.cpp -Ofast -o "${_precompiled}"`);
- console.log("[+] Compiling with precompiled Nectar lib");
- }
-
- if(compiler == "cl" || compiler.indexOf("cl ") == 0)
- {
- if(_stack) _stack = "/F " + _stack;
- else _stack = "";
-
- if(preset == "none") return `${compiler} ${_stack} ${_in} /D __NJS_REGISTER_SIZE=${COMPILER.REGISTER} /std:c++14 /D CL_WINDOWS=1 /I "${CONFIG.win_inc_ucrt}" "${CONFIG.win_lib_um}\\Uuid.Lib" "${CONFIG.win_lib_um}\\kernel32.Lib" "${CONFIG.win_lib_ucrt}\\libucrt.lib" /EHsc ${COMPILER.LIBS} /o ${out}`;
- else if(preset == "size") return `${compiler} ${_stack} ${_in} /D __NJS_REGISTER_SIZE=${COMPILER.REGISTER} /std:c++14 /D CL_WINDOWS=1 /O1 /I "${CONFIG.win_inc_ucrt}" "${CONFIG.win_lib_um}\\Uuid.Lib" "${CONFIG.win_lib_um}\\kernel32.Lib" "${CONFIG.win_lib_ucrt}\\libucrt.lib" /EHsc ${COMPILER.LIBS} /o ${out}`;
- else if(preset == "speed") return `${compiler} ${_stack} ${_in} /D __NJS_REGISTER_SIZE=${COMPILER.REGISTER} /std:c++14 /D CL_WINDOWS=1 /Ox /I "${CONFIG.win_inc_ucrt}" "${CONFIG.win_lib_um}\\Uuid.Lib" "${CONFIG.win_lib_um}\\kernel32.Lib" "${CONFIG.win_lib_ucrt}\\libucrt.lib" /EHsc ${COMPILER.LIBS} /o ${out}`;
- }
-
- var _hashmap = "-D__NJS__OBJECT_HASHMAP";
- if(CLI.cli['--no-object-hashmap']) _hashmap = "";
-
- var _uvParam = "";
- if(os.platform() == "win32") _uvParam = `-D_WIN32_WINNT=0x0600 -Wno-narrowing -D_GNU_SOURCE -I${extern}/libuv/include/ -I${extern}/libuv/src/ -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE ${extern}/libuv/src/*.h ${extern}/libuv/src/*.c ${extern}/libuv/src/win/*.h ${extern}/libuv/src/win/*.c`;
-
- var _uvLib = "-luv ";
- if(os.platform() == "win32") _uvLib = "-lm -ladvapi32 -liphlpapi -lpsapi -lshell32 -luser32 -luserenv -lwsock32 -lws2_32";
- if(os.platform() == "sunos") _uvLib += "-lkstat -lsendfile -lsocket -lnsl";
-
- if(_stack) _stack = "-Wl,--stack," + _stack;
- else _stack = "";
- var _cliOption = "";
- if(CLI.cli["--option"]) _cliOption = CLI.cli["--option"].argument;
-
- var _files = `"${_precompiled}" "${_in}"`;
- if(os.platform == "win32") _files = `"${_in}" "${_precompiled}"`;
-
- if(preset == "none")
- {
- return `${compiler} ${_hashmap} -D__NJS_REGISTER_SIZE=${COMPILER.REGISTER} ${_stack} -std=c++17 ${_uvParam} ${_files} -O1 -s ${COMPILER.LIBS} ${_uvLib} -o a.exe && mv a.exe ${out} ${_cliOption}`;
- }
- else if(preset == "size")
- {
- return `${compiler} ${_hashmap} -D__NJS_REGISTER_SIZE=${COMPILER.REGISTER} ${_stack} -std=c++17 ${_uvParam} ${_files} -Os -fno-rtti -fno-stack-protector -fomit-frame-pointer -s ${COMPILER.LIBS} ${_uvLib} -o a.exe && mv a.exe ${out} ${_cliOption}`;
- }
- else
- {
- var _opt = "-O";
- if(os.platform() == "darwin" || compiler.indexOf("clang") > -1) _opt += "3";
- else _opt += "fast";
- console.log(`${compiler} ${_hashmap} -D__NJS_REGISTER_SIZE=${COMPILER.REGISTER} ${_stack} -std=c++17 ${_uvParam} ${_files} ${_opt} -s ${COMPILER.LIBS} ${_uvLib} -o a.exe && mv a.exe ${out} ${_cliOption}`);
- return `${compiler} ${_hashmap} -D__NJS_REGISTER_SIZE=${COMPILER.REGISTER} ${_stack} -std=c++17 ${_uvParam} ${_files} ${_opt} -s ${COMPILER.LIBS} ${_uvLib} -o a.exe && mv a.exe ${out} ${_cliOption}`;
- }
- }
-}
-
-module.exports = NODE;
diff --git a/compiler/native/env/std.js b/compiler/native/env/std.js
index eaa85e931..7f55a4df4 100644
--- a/compiler/native/env/std.js
+++ b/compiler/native/env/std.js
@@ -1,61 +1,36 @@
-//TODO for (NaN == NaN) -> false correctness, we need the -fno-finite-math-only flag with -Ofast
+/*
+ Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
-var os = require("os");
+ 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.
+
+*/
+var _debug = " -g ";
var STD =
{
name: "std",
main: "std.cpp",
compiler: "g++",
- stdlib: ["console", {bind:"performance", module:"Performance"}, "Error", "RegExp", "Number", "Object", "Math", "JSON", "Array", "Date"],
- check:
- {
- "env":
- {
- "es6": true
- },
- "extends": "eslint:recommended",
- "rules":
- {
- "strict": "global",
- "no-console": "off",
- "indent": "off",
- "linebreak-style": "off",
- "no-unused-vars": ["warn", { "vars": "all", "args": "after-used", "ignoreRestSiblings": false }],
- "no-const-assign": "error",
- },
- "globals":
- {
- "undefined": false,
- "eval": false,
- "__njs_typeof": false,
- "console": false,
- "module": false,
- "require": false,
- "__Nectar_Log_Console": false,
- "__Nectar_InitVar": false,
- "__Nectar_Object_Keys": false,
- "__Nectar_Object_Stringify": false,
- "__Nectar_Call_Function": false,
- "__NJS_ARGS": false,
- "__NJS_ENV": false,
- "__NJS_PLATFORM": false,
- "__Nectar_typeof": false,
- "__Nectar_THIS": false,
- "__Nectar_instanceof": false,
- "__Nectar_delete": false,
- "__Nectar_EQUAL_VALUE_AND_TYPE": false,
- "__Nectar_NOT_EQUAL_VALUE_AND_TYPE": false,
- "JSON": false,
- "Object": false,
- "isNaN": false,
- "Array": false,
- },
- },
+ stdlib: [],
cli: function(compiler, preset, out, _in, option)
{
var _cachePath = path.join(process.cwd(), "..", "cached_" + COMPILER.ENV.name + "_" + os.platform + "_" + VERSION);
- var _precompiled = path.join(_cachePath, "nectar.o");
+ var _precompiled = path.join(_cachePath, "nerd.o");
var _stack = 0;
if(CLI.cli["--stack"])
@@ -73,10 +48,19 @@ var STD =
if(!fs.existsSync(_precompiled))
{
- console.log(`[+] Creating Nectar binary lib for ${COMPILER.ENV.name + "_" + os.platform + "_" + VERSION}`);
+
+ var _args = " -flto -Ofast ";
+ if(preset == "debug")
+ {
+ console.log("Building core with debug");
+ _args = _debug;
+ }
+
+ console.log(`[+] Creating Nerd binary lib for ${COMPILER.ENV.name + "_" + os.platform + "_" + VERSION}`);
+ console.log(`${compiler} -std=c++17 ${_args} -c nerdcore/src/nerd.cpp -o "${_precompiled}"`);
try { fs.mkdirSync(_cachePath); } catch(e){};
- execSync(`${compiler} -std=c++17 -c nectar.cpp -Ofast -o "${_precompiled}"`);
- console.log("[+] Compiling with precompiled Nectar lib");
+ execSync(`${compiler} -std=c++17 ${_args} -c nerdcore/src/nerd.cpp -o "${_precompiled}"`);
+ console.log("[+] Compiling with precompiled Nerd lib");
}
if(compiler == "cl" || compiler.indexOf("cl ") == 0)
@@ -85,8 +69,8 @@ var STD =
process.exit(1);
}
- var _hashmap = "-D__Nectar__OBJECT_HASHMAP";
- if(CLI.cli['--no-object-hashmap']) _hashmap = "";
+ var _hashmap = "";
+ if(CLI.cli['--no-object-hashmap']) _hashmap = "-D__NERD__OBJECT_VECTOR";
if(_stack) _stack = "-Wl,--stack," + _stack;
else _stack = "";
@@ -122,19 +106,24 @@ var STD =
if(preset == "none")
{
- return `${compiler} ${_stack} -std=c++17 ${_files} -O1 -s ${COMPILER.LIBS} -lpthread -o "${out}" ${_sysVNetLibs} ${_cliOption}`;
+ return `${compiler} ${_stack} -std=c++17 ${_files} -g -s ${COMPILER.LIBS} -pthread -o "${out}" ${_sysVNetLibs} ${_cliOption}`;
+ }
+ else if(preset == "debug")
+ {
+ console.log(`${compiler} ${_stack} -std=c++17 ${_files} ${_debug} -s ${COMPILER.LIBS} -pthread -o "${out}" ${_sysVNetLibs} ${_cliOption}`);
+ return `${compiler} ${_stack} -std=c++17 ${_files} ${_debug} -s ${COMPILER.LIBS} -pthread -o "${out}" ${_sysVNetLibs} ${_cliOption}`;
}
else if(preset == "size")
{
- return `${compiler} ${_stack} -std=c++17 ${_files} -lpthread -Os -fno-rtti -fno-stack-protector -fomit-frame-pointer -s ${COMPILER.LIBS} -o "${out}" ${_sysVNetLibs} ${_cliOption}`;
+ return `${compiler} ${_stack} -std=c++17 ${_files} -pthread -Os -fno-rtti -fno-stack-protector -fomit-frame-pointer -s ${COMPILER.LIBS} -o "${out}" ${_sysVNetLibs} ${_cliOption}`;
}
else
{
var _opt = "-O";
if(os.platform() == "darwin" || compiler.indexOf("clang") > -1) _opt += "3";
else _opt += "fast";
-
- return `${compiler} ${_stack} -std=c++17 ${_files} ${_opt} -lpthread -s ${COMPILER.LIBS} -o "${out}" ${_sysVNetLibs} ${_cliOption}`;
+ _opt += " -flto";
+ return `${compiler} ${_stack} -std=c++17 ${_files} ${_opt} -pthread -s ${COMPILER.LIBS} -o "${out}" ${_sysVNetLibs} ${_cliOption}`;
}
},
write: function(_content, _in)
diff --git a/compiler/native/env/stm32.js b/compiler/native/env/stm32.js
deleted file mode 100644
index 3faef0bf8..000000000
--- a/compiler/native/env/stm32.js
+++ /dev/null
@@ -1,70 +0,0 @@
-var STM32 =
-{
- name: "stm32",
- main: "stm32.cpp",
- cli: function(compiler, preset, out, _in, option)
- {
- if(!COMPILER.TARGET)
- {
- console.log("[!] Error: please specify a target with --target");
- process.exit(1);
- }
-
- var _mbosSrc = path.join(extern, "stm32", "mbed-os", "nectar");
- copyDirSync(COMPILER.TMP_FOLDER, _mbosSrc, true);
-
- var _profile = "SIZE";
- if(COMPILER.preset == "speed") _profile = "SPEED";
-
- return `cd ${path.join(extern, "stm32")} && ${compiler} compile -m ${COMPILER.TARGET} --profile ${path.join(extern, "stm32", "profile", _profile + ".json")} -t GCC_ARM > stm32_debug_res.txt && mv ${path.join(extern, "stm32", "BUILD", COMPILER.TARGET, "GCC_ARM-" + _profile)}/stm32.bin ${out}`;
- },
- clean: function()
- {
- var _mbosSrc = path.join(extern, "stm32", "mbed-os", "nectar");
- rmdir(_mbosSrc);
- },
- compiler: "mbed",
- stdlib:[{bind: "Nectar", module: "stm32"}],
- check: {
- "env": {
- "node": true
- },
- "extends": "eslint:recommended",
- "rules": {
- "no-console": "off",
- "indent": "off",
- "linebreak-style": "off",
- "no-unused-vars": ["warn", { "vars": "all", "args": "after-used", "ignoreRestSiblings": false }],
- "no-const-assign": "error",
- },
- "globals":
- {
- "undefined": false,
- "eval": false,
- "__njs_typeof": false,
- "console": false,
- "module": false,
- "require": false,
- "__Nectar_Log_Console": false,
- "__Nectar_InitVar": false,
- "__Nectar_Object_Keys": false,
- "__Nectar_Object_Stringify": false,
- "__Nectar_Call_Function": false,
- "__NJS_ARGS": false,
- "__NJS_ENV": false,
- "__NJS_PLATFORM": false,
- "__Nectar_typeof": false,
- "__Nectar_THIS": false,
- "__Nectar_instanceof": false,
- "__Nectar_delete": false,
- "__Nectar_EQUAL_VALUE_AND_TYPE": false,
- "__Nectar_NOT_EQUAL_VALUE_AND_TYPE": false,
- "JSON": false,
- "Object": false,
- "isNaN": false,
- "Array": false,
- }
- }
-}
-
-module.exports = STM32;
diff --git a/compiler/native/env/test.js b/compiler/native/env/test.js
deleted file mode 100644
index 4c312334b..000000000
--- a/compiler/native/env/test.js
+++ /dev/null
@@ -1,88 +0,0 @@
-var os = require("os");
-
-var TEST =
-{
- name: "test",
- main: "test.cpp",
- compiler: "g++",
- stdlib: [],
- cli: function(compiler, preset, out, _in, option)
- {
- var _cachePath = path.join(process.cwd(), "..", "cached_" + COMPILER.ENV.name + "_" + os.platform + "_" + VERSION);
- var _precompiled = path.join(_cachePath, "nectar.o");
- if(!fs.existsSync(_precompiled))
- {
- console.log(`[+] Creating Nectar binary lib for ${COMPILER.ENV.name + "_" + os.platform + "_" + VERSION}`);
- try { fs.mkdirSync(_cachePath); } catch(e){};
- execSync(`${compiler} -std=c++17 -c nectar.cpp -Ofast -o "${_precompiled}"`);
- console.log("[+] Compiling with precompiled Nectar lib");
- }
-
- if(compiler == "cl" || compiler.indexOf("cl ") == 0)
- {
- if(preset == "none") return `${compiler} ${_in} /std:c++17 /D CL_WINDOWS=1 /I "${CONFIG.win_inc_ucrt}" "${CONFIG.win_lib_um}\\Uuid.Lib" "${CONFIG.win_lib_um}\\kernel32.Lib" "${CONFIG.win_lib_ucrt}\\libucrt.lib" /EHsc ${COMPILER.LIBS} /o ${out}`;
- else if(preset == "size") return `${compiler} ${_in} /std:c++17 /D CL_WINDOWS=1 /O1 /I "${CONFIG.win_inc_ucrt}" "${CONFIG.win_lib_um}\\Uuid.Lib" "${CONFIG.win_lib_um}\\kernel32.Lib" "${CONFIG.win_lib_ucrt}\\libucrt.lib" /EHsc ${COMPILER.LIBS} /o ${out}`;
- else if(preset == "speed") return `${compiler} ${_in} /std:c++17 /D CL_WINDOWS=1 /Ox /I "${CONFIG.win_inc_ucrt}" "${CONFIG.win_lib_um}\\Uuid.Lib" "${CONFIG.win_lib_um}\\kernel32.Lib" "${CONFIG.win_lib_ucrt}\\libucrt.lib" /EHsc ${COMPILER.LIBS} /o ${out}`;
- }
-
- var _cliOption = "";
- if(CLI.cli["--option"]) _cliOption = CLI.cli["--option"].argument;
-
- var _files = `"${_precompiled}" "${_in}"`;
- if(os.platform == "win32") _files = `"${_in}" "${_precompiled}"`;
-
- if(preset == "none")
- {
- return `${compiler} -std=c++17 ${_files} ${option} -I ${extern}/lib/ -s ${COMPILER.LIBS} -o ${out} ${_cliOption}`;
- }
- else if(preset == "size")
- {
- return `${compiler} -std=c++17 ${_files} ${option} -I ${extern}/lib/ -fno-rtti -fno-stack-protector -fomit-frame-pointer -s ${COMPILER.LIBS} -o ${out} ${_cliOption}`;
- }
- else return `${compiler} -std=c++17 ${_files} -I ${extern}/lib/ ${option} -s ${COMPILER.LIBS} -o ${out} ${_cliOption}`;
- },
- check: {
- "env": {
- "es6": true
- },
- "extends": "eslint:recommended",
- "rules": {
- "strict": "global",
- "no-console": "off",
- "indent": "off",
- "linebreak-style": "off",
- "no-unused-vars": ["warn", { "vars": "all", "args": "after-used", "ignoreRestSiblings": false }],
- "no-const-assign": "error",
- },
- "globals":
- {
- "undefined": false,
- "eval": false,
- "__njs_typeof": false,
- "console": false,
- "module": false,
- "require": false,
- "__Nectar_Log_Console": false,
- "__Nectar_InitVar": false,
- "__Nectar_Object_Keys": false,
- "__Nectar_Object_Stringify": false,
- "__Nectar_Call_Function": false,
- "__NJS_ARGS": false,
- "__NJS_ENV": false,
- "__NJS_PLATFORM": false,
- "__Nectar_typeof": false,
- "__Nectar_THIS": false,
- "__Nectar_instanceof": false,
- "__Nectar_delete": false,
- "__Nectar_EQUAL_VALUE_AND_TYPE": false,
- "__Nectar_NOT_EQUAL_VALUE_AND_TYPE": false,
- "JSON": false,
- "Object": false,
- "isNaN": false,
- "Array": false,
- "$ERROR": false,
- }
-}
-}
-
-module.exports = TEST;
diff --git a/compiler/native/env/wasm.js b/compiler/native/env/wasm.js
index 72a8cd045..bb047203f 100644
--- a/compiler/native/env/wasm.js
+++ b/compiler/native/env/wasm.js
@@ -3,49 +3,7 @@ var WASM =
name: "wasm",
main: "wasm.cpp",
compiler: "em++",
- stdlib: [{bind: "Nectar", module: "WASM"},"console", "Math", "JSON"],
- check: {
- "env": {
- "node": true,
- "es6": true
- },
- "extends": "eslint:recommended",
- "rules": {
- "no-console": "off",
- "indent": "off",
- "linebreak-style": "off",
- "no-unused-vars": ["warn", { "vars": "all", "args": "after-used", "ignoreRestSiblings": false }],
- "no-const-assign": "error",
- },
- "globals":
- {
- "undefined": false,
- "eval": false,
- "__njs_typeof": false,
- "console": false,
- "module": false,
- "require": false,
- "__Nectar_Log_Console": false,
- "__Nectar_InitVar": false,
- "__Nectar_Object_Keys": false,
- "__Nectar_Object_Stringify": false,
- "__Nectar_Call_Function": false,
- "__NJS_ARGS": false,
- "__NJS_ENV": false,
- "__NJS_PLATFORM": false,
- "__Nectar_typeof": false,
- "__Nectar_THIS": false,
- "__Nectar_instanceof": false,
- "__Nectar_delete": false,
- "__Nectar_EQUAL_VALUE_AND_TYPE": false,
- "__Nectar_NOT_EQUAL_VALUE_AND_TYPE": false,
- "JSON": false,
- "Object": false,
- "isNaN": false,
- "Array": false,
- }
- },
- out: function(_name)
+ out: function(_name)
{
if(CLI.cli["--target"])
{
@@ -64,14 +22,14 @@ var WASM =
{
/*
var _cachePath = path.join(process.cwd(), "..", "cached_" + COMPILER.ENV.name + "_" + VERSION);
- var _precompiled = path.join(_cachePath, "nectar.o");
+ var _precompiled = path.join(_cachePath, "nerd.o");
if(!fs.existsSync(_precompiled))
{
- console.log(`[+] Creating Nectar binary lib for ${COMPILER.ENV.name + "_" + VERSION}`);
+ console.log(`[+] Creating Nerd binary lib for ${COMPILER.ENV.name + "_" + VERSION}`);
try { fs.mkdirSync(_cachePath); } catch(e){};
- execSync(`${compiler} -std=c++17 -c nectar.cpp -O3 -o "${_precompiled}"`);
- console.log("[+] Compiling with precompiled Nectar lib");
+ execSync(`${compiler} -std=c++17 -c nerd.cpp -O3 -o "${_precompiled}"`);
+ console.log("[+] Compiling with precompiled Nerd lib");
}
*/
var _cliOption = "";
@@ -79,15 +37,15 @@ var WASM =
if(preset == "none")
{
- return `${compiler} -D__NJS_REGISTER_SIZE=${COMPILER.REGISTER} ${_in} -O1 -w -s TOTAL_MEMORY=33554432 ${COMPILER.LIBS} -o ${out} ${_cliOption}`;
+ return `${compiler} nerdcore/src/nerd.cpp -D__NJS_REGISTER_SIZE=${COMPILER.REGISTER} ${_in} -O1 -w -s TOTAL_MEMORY=33554432 ${COMPILER.LIBS} -o ${out} ${_cliOption}`;
}
else if(preset == "size")
{
- return `${compiler} -D__NJS_REGISTER_SIZE=${COMPILER.REGISTER} ${_in} -Os -fno-exceptions -fno-rtti -fno-stack-protector -fomit-frame-pointer -w -s TOTAL_MEMORY=33554432 ${COMPILER.LIBS} -o ${out} ${_cliOption}`;
+ return `${compiler} nerdcore/src/nerd.cpp -D__NJS_REGISTER_SIZE=${COMPILER.REGISTER} ${_in} -Os -fno-rtti -fno-stack-protector -fomit-frame-pointer -w -s TOTAL_MEMORY=33554432 ${COMPILER.LIBS} -o ${out} ${_cliOption}`;
}
else
{
- return `${compiler} -D__NJS_REGISTER_SIZE=${COMPILER.REGISTER} ${_in} -O3 -w -s TOTAL_MEMORY=33554432 ${COMPILER.LIBS} -o ${out} ${_cliOption}`;
+ return `${compiler} nerdcore/src/nerd.cpp -D__NJS_REGISTER_SIZE=${COMPILER.REGISTER} ${_in} -O3 -w -s TOTAL_MEMORY=33554432 ${COMPILER.LIBS} -o ${out} ${_cliOption}`;
}
}
}
diff --git a/compiler/native/lib/createAnon.js b/compiler/native/lib/createAnon.js
deleted file mode 100644
index 5d366cc2c..000000000
--- a/compiler/native/lib/createAnon.js
+++ /dev/null
@@ -1,72 +0,0 @@
-function createAnon(_code, _scope)
-{
- var _return = "return NectarCore::Global::undefined;}";
- var _searchAnonFN = new RegExp(/(var)* *([\[\]a-zA-Z0-9_"]*) *= *function +\(([a-zA-Z0-9_\-, ]*)\)/);
- var _index = _code.search(_searchAnonFN);
-
- while(_index > -1)
- {
- var _var = "";
- var _count = 0;
- var _start = -1;
- var _end = -1;
- var _genFN = "__NJS_FN_" + RND();
- var _genVAR = "NectarCore::VAR_" + RND();
-
- var _match = _searchAnonFN.exec(_code);
- _match[3] = _match[3].split(",");
- var _getVar = "";
-
- for(var i = 0; i < _match[3].length; i++)
- {
- if(_match[3][i].length > 0)
- {
- _getVar += `var ${_match[3][i]}; if(__Nectar_VARLENGTH > ${i}) ${_match[3][i]} = __Nectar_VARARGS[${i}];`;
- }
- }
-
- for(var i = _index; i < _code.length; i++)
- {
- if(_code[i] == "{")
- {
- if(_start == -1) _start = i;
- _count++;
- }
- else if(_code[i] == "}")
- {
- var _catch = "";
- var _classAnon = false;
- if(_scope) _catch = "&";
- if(_code.indexOf("\"SCOPED_FUNCTION\";") > -1)
- {
- _code = _code.replace(/"SCOPED_FUNCTION";/g, " ");
- _catch = "&";
- }
- if(_code.indexOf("'__NJS_CLASS_ANON__';") > -1)
- {
- _code = _code.replace(/'__NJS_CLASS_ANON__';/g, " ");
- _classAnon = true;
- }
-
- _end = i;
- _count--;
- if(_count == 0)
- {
- var _fn = "{" + _getVar + _code.substring(_start + 1, _end);
- if(_classAnon) _fn = "{" + _getVar + _code.substring(_start + 1, _end);
- var _formated = "";
-
- if(_match[1]) COMPILER.DECL.push(`var ${_match[2]};`);
- if(_match[2]) _formated += _match[2] + " = ";
- _formated += "NectarCore::VAR(NectarCore::Enum::Type::Function, new NectarCore::Type::function_t ([" + _catch + "](var __Nectar_THIS, NectarCore::VAR* __Nectar_VARARGS, int __Nectar_VARLENGTH) -> NectarCore::VAR" + _fn + os.EOL + _return + "), __Nectar_THIS);";
- _code = [_code.slice(0, _index), ' ', _formated, _code.slice(_end + 1)].join('');
- break;
- }
- }
- }
- _index = _code.search(_searchAnonFN);
- }
- _code = replaceObjAddr(_code);
- return _code;
-}
-module.exports = createAnon;
diff --git a/compiler/native/lib/createClass.js b/compiler/native/lib/createClass.js
deleted file mode 100644
index c19d1fa90..000000000
--- a/compiler/native/lib/createClass.js
+++ /dev/null
@@ -1,68 +0,0 @@
-function createClass(_code, _scope)
-{
- var _matchThis = new RegExp(/(| |{|,)__Nectar_THIS([\.(";)]|$)/);
- var _return = ";return NectarCore::Global::undefined;}";
- var _returnThis = ";return __Nectar_THIS;}";
- var _searchFN = new RegExp(/function +__Nectar_CLASS_(.[a-zA-Z0-9_\-]*) *\((.*)\)/);
- var _index = _code.search(_searchFN);
-
- while(_index > -1)
- {
- var _genFN = "__NJS_FN_" + RND();
-
- var _var = "";
- var _count = 0;
- var _start = -1;
- var _end = -1;
-
- let _match = _searchFN.exec(_code);
-
- _match[2] = _match[2].split(",");
-
- var _getVar = "";
- for(var i = 0; i < _match[2].length; i++)
- {
- if(_match[2][i].length > 0)
- {
- _getVar += `var ${_match[2][i]}; if(__Nectar_VARLENGTH > ${i}) ${_match[2][i]} = __Nectar_VARARGS[${i}];`;
- }
- }
- for(var i = _index; i < _code.length; i++)
- {
- if(_code[i] == "{")
- {
- if(_start == -1) _start = i;
- _count++;
- }
- else if(_code[i] == "}")
- {
- var _catch = "";
- if(_scope) _catch = "&";
- if(_code.indexOf("\"SCOPED_FUNCTION\";") > -1)
- {
- _code = _code.replace(/'SCOPED_Function';/g, " ");
- _catch = "&";
- }
-
- _end = i;
- _count--;
- if(_count == 0)
- {
- var _fn = "{" + _getVar + _code.substring(_start + 1, _end);
-
- COMPILER.DECL.push("var " + _match[1] +";");
-
- var _formated = "NectarCore::Type::function_t* " + _genFN +" = new NectarCore::Type::function_t([" + _catch + "](var __Nectar_THIS, NectarCore::VAR* __Nectar_VARARGS, int __Nectar_VARLENGTH) -> NectarCore::VAR" + _fn + _return + ");";
- _formated += _match[1] + "=NectarCore::VAR(NectarCore::Enum::Type::Function, " + _genFN + ", __Nectar_THIS);";
-
- _code = [_code.slice(0, _index), _formated, _code.slice(_end + 1)].join('');
- break;
- }
- }
- }
- _index = _code.search(_searchFN);
- }
- _code = replaceObjAddr(_code);
- return _code;
-}
-module.exports = createClass;
diff --git a/compiler/native/lib/createFunction.js b/compiler/native/lib/createFunction.js
deleted file mode 100644
index 5c0912952..000000000
--- a/compiler/native/lib/createFunction.js
+++ /dev/null
@@ -1,124 +0,0 @@
-function createFunction(_code, _scope)
-{
- var _return = ";return NectarCore::Global::undefined;}";
- var _searchFN = new RegExp(/function +(.[a-zA-Z0-9_\-]*) *\((.*)\)/);
- var _index = _code.search(_searchFN);
- while(_index > -1)
- {
- var _genFN = "__NJS_FN_" + RND();
- var _genVAR = "NectarCore::VAR_" + RND();
-
- var _var = "";
- var _count = 0;
- var _start = -1;
- var _end = -1;
-
- let _match = _searchFN.exec(_code);
- _match[2] = _match[2].split(",");
- var _getVar = "";
- var _parameters = "";
- var _variadic = false;
-
- var _FAST = false;
-
- if(!CLI.cli["--no-fast-function"] && COMPILER.INFO.SCOPE[_match[1]] && COMPILER.INFO.SCOPE[_match[1]].fast == true && COMPILER.INFO.SCOPE[_match[1]].param.length == 1 && COMPILER.INFO.SCOPE[_match[1]].param[0] == _match[2].length)
- {
- _FAST = true;
- for(var i = 0; i < _match[2].length; i++)
- {
- if(_match[2][i].length > 0)
- {
- if(i != 0) _var += ",";
- _var += "double " + _match[2][i];
- }
- }
- _parameters = _var;
- }
- else
- {
-
- _variadic = true;
- _parameters = "var __Nectar_THIS, NectarCore::VAR* __Nectar_VARARGS, int __Nectar_VARLENGTH";
-
- if(COMPILER.INFO.SCOPE[_match[1]] && COMPILER.INFO.SCOPE[_match[1]].param.length == 1)
- {
- for(var i = 0; i < _match[2].length; i++)
- {
- if(_match[2][i].length > 0)
- {
- if(i <= COMPILER.INFO.SCOPE[_match[1]].param.length)
- {
- _getVar += `var ${_match[2][i]} = __Nectar_VARARGS[${i}];`;
- }
- else _getVar += `var ${_match[2][i]}; if(__Nectar_VARLENGTH > ${i}) ${_match[2][i]} = __Nectar_VARARGS[${i}];`;
- }
- }
- }
- else
- {
- for(var i = 0; i < _match[2].length; i++)
- {
- if(_match[2][i].length > 0)
- {
- _getVar += `var ${_match[2][i]}; if(__Nectar_VARLENGTH > ${i}) ${_match[2][i]} = __Nectar_VARARGS[${i}];`;
- }
- }
- }
- }
-
- for(var i = _index; i < _code.length; i++)
- {
- if(_code[i] == "{")
- {
- if(_start == -1) _start = i;
- _count++;
- }
- else if(_code[i] == "}")
- {
-
- _end = i;
- _count--;
- if(_count == 0)
- {
-
- if(!_FAST)
- {
- var _catch = "";
- if(_scope) _catch = "&";
- if(_code.indexOf("\"SCOPED_FUNCTION\";") > -1)
- {
- _code = _code.replace(/'SCOPED_Function';/g, " ");
- _catch = "&";
- }
- _catch = "&";
- var _constructor = `${_match[1]}["prototype"]["constructor"] = __Nectar_Create_Var_Scoped_Anon(return __Nectar_THIS;);`;
- var _fn = "{" + _getVar + _code.substring(_start + 1, _end);
-
- COMPILER.DECL.push("var " + _match[1] +";");
-
- var __STR_MARKER = "__LIT" + RND();
- var _formated = `NectarCore::Type::function_t* ${_genFN} = new NectarCore::Type::function_t([${_catch}]( ${_parameters} ) -> NectarCore::VAR ${_fn} ${_return} );`;
- _formated += _match[1] + "=NectarCore::VAR(NectarCore::Enum::Type::Function, " + _genFN + ");";
- if(CLI.cli["--debug"]) _formated += `((NectarCore::Class::Function*)${_match[1]}._ptr)->code = R"${__STR_MARKER}(Function ${_match[1]}(${_match[2]}) ${_code.substring(_start, _end )}})${__STR_MARKER}";`
- //else _formated += `((NectarCore::Class::Function*)${_match[1]}._ptr)->code = R"([Function: ${_match[1]}])";`
-
- _code = [_code.slice(0, _index), _formated, _code.slice(_end + 1)].join('');
- }
- else
- {
- // FAST CALL HERE
- var _fn = _code.substring(_start, _end);
- COMPILER.DECL.push(`__Nectar_FAST_INT ${_match[1]}(${_parameters})${_fn}; return 0;}`);
- _code = [_code.slice(0, _index), _code.slice(_end + 1)].join('');
- }
-
- break;
- }
- }
- }
- _index = _code.search(_searchFN);
- }
- _code = replaceObjAddr(_code);
- return _code;
-}
-module.exports = createFunction;
\ No newline at end of file
diff --git a/compiler/native/lib/createReturnAnon.js b/compiler/native/lib/createReturnAnon.js
deleted file mode 100644
index 9d9e815b6..000000000
--- a/compiler/native/lib/createReturnAnon.js
+++ /dev/null
@@ -1,72 +0,0 @@
-function createReturnAnon(_code, _scope)
-{
- var _return = "return NectarCore::Global::undefined;}";
- var _searchAnonFN = new RegExp(/return *function +\(([a-zA-Z0-9_\-, ]*)\)/);
- var _index = _code.search(_searchAnonFN);
-
- while(_index > -1)
- {
- var _var = "";
- var _count = 0;
- var _start = -1;
- var _end = -1;
- var _genFN = "__NJS_FN_" + RND();
- var _genVAR = "NectarCore::VAR_" + RND();
-
- var _match = _searchAnonFN.exec(_code);
- _match[1] = _match[1].split(",");
- var _getVar = "";
-
-
- for(var i = 0; i < _match[1].length; i++)
- {
- if(_match[1][i].length > 0)
- {
- _getVar += `var ${_match[1][i]}; if(__Nectar_VARLENGTH > ${i}) ${_match[1][i]} = __Nectar_VARARGS[${i}];`;
- }
- }
-
- for(var i = _index; i < _code.length; i++)
- {
- if(_code[i] == "{")
- {
- if(_start == -1) _start = i;
- _count++;
- }
- else if(_code[i] == "}")
- {
- var _catch = "";
- var _classAnon = false;
- if(_scope) _catch = "&";
- if(_code.indexOf("\"SCOPED_FUNCTION\";") > -1)
- {
- _code = _code.replace(/"SCOPED_FUNCTION";/g, " ");
- _catch = "&";
- }
- if(_code.indexOf("'__NJS_CLASS_ANON__';") > -1)
- {
- _code = _code.replace(/'__NJS_CLASS_ANON__';/g, " ");
- _classAnon = true;
- }
-
- _end = i;
- _count--;
- if(_count == 0)
- {
- var _fn = "{" + _getVar + _code.substring(_start + 1, _end);
- if(_classAnon) _fn = "{" + _getVar + _code.substring(_start + 1, _end);
- var _formated = "";
-
- _formated += "return NectarCore::VAR(NectarCore::Enum::Type::Function, new NectarCore::Type::function_t ([" + _catch + "](var __Nectar_THIS, NectarCore::VAR* __Nectar_VARARGS, int __Nectar_VARLENGTH) -> NectarCore::VAR" + _fn + os.EOL + _return + "), __Nectar_THIS);";
-
- _code = [_code.slice(0, _index), ' ', _formated, _code.slice(_end + 1)].join('');
- break;
- }
- }
- }
- _index = _code.search(_searchAnonFN);
- }
- _code = replaceObjAddr(_code);
- return _code;
-}
-module.exports = createReturnAnon;
diff --git a/compiler/native/lib/genInclude.js b/compiler/native/lib/genInclude.js
deleted file mode 100644
index c3c401573..000000000
--- a/compiler/native/lib/genInclude.js
+++ /dev/null
@@ -1,50 +0,0 @@
-var _SEARCH = new RegExp(/['"]!_ffi_include *(.*)['"]/);
-var _SEARCHCINC = new RegExp(/#include *\"(.*)\"/g);
-
-function genInclude(from, src, full)
-{
- if(CLI.cli["--profile"] && CLI.cli["--profile"].argument == "use")
- {
- return src;
- }
- var _match = src.match(_SEARCH);
- while(_match)
- {
- var _var = "#include \"" + path.resolve(path.join(COMPILER.TMP_FOLDER, _match[1]) + "\"");
- COMPILER.FFI.push(_var);
- copyRecursiveSync(path.resolve(path.join(from, _match[1])), path.join(COMPILER.TMP_FOLDER, _match[1]));
- var _include = fs.readFileSync(path.resolve(path.join(COMPILER.TMP_FOLDER, _match[1]))).toString();
- _include = genMetaFunction(_include);
- _include = genInclude(path.dirname(path.resolve(path.join(from, _match[1]))), _include, path.dirname(path.resolve(path.join(COMPILER.TMP_FOLDER, _match[1]))));
- fs.writeFileSync(path.resolve(path.join(COMPILER.TMP_FOLDER, _match[1])), _include);
- src = src.replace(/['"]!_ffi_include *(.*)['"]/, "");
- _match = src.match(_SEARCH);
- }
-
-
- var _cmatch = src.match(_SEARCHCINC);
- if(_cmatch)
- {
- for(var i = 0; i < _cmatch.length; i++)
- {
- var _getPath = new RegExp(/#include *\"(.*)\"/g);
- var _cfile = _getPath.exec(_cmatch[i]);
- if(_cfile[1])
- {
- var _incFile = path.resolve(path.join(from, _cfile[1]));
- if(fs.existsSync(_incFile))
- {
- copyRecursiveSync(_incFile, path.join(full, _cfile[1]));
- var _include = fs.readFileSync(path.resolve(path.join(full, _cfile[1]))).toString();
- _include = genMetaFunction(_include);
- _include = genInclude(path.dirname(path.resolve(path.join(full, _cfile[1]))), _include, path.dirname(path.resolve(path.join(full, _cfile[1]))));
- fs.writeFileSync(path.resolve(path.join(full, _cfile[1])), _include);
- _cmatch = src.match(_SEARCHCINC);
- }
- }
- }
- }
-
- return src;
-}
-module.exports = genInclude;
diff --git a/compiler/native/lib/genMetaFunction.js b/compiler/native/lib/genMetaFunction.js
deleted file mode 100644
index 472b6fea8..000000000
--- a/compiler/native/lib/genMetaFunction.js
+++ /dev/null
@@ -1,61 +0,0 @@
-global.RND = function() { return "__META_" + Math.random().toString(36).substring(7); };
-
-function genMetaFunction(_code)
-{
- var _return = ";return NectarCore::Global::undefined;}";
- var _searchFN = new RegExp(/function (.[a-zA-Z0-9_\-]*) *\((.*)\)/);
- var _index = _code.search(_searchFN);
- while(_index > -1)
- {
- var _genFN = "__NJS_FN_" + RND();
- var _count = 0;
- var _start = -1;
- var _end = -1;
-
- let _match = _searchFN.exec(_code);
-
- _match[2] = _match[2].split(",");
- var _getVar = "";
- for(var i = 0; i < _match[2].length; i++)
- {
- if(_match[2][i].length > 0)
- {
- _getVar += `var ${_match[2][i]}; if(__Nectar_VARLENGTH > ${i}) ${_match[2][i]} = __Nectar_VARARGS[${i}];`;
- }
- }
- for(var i = _index; i < _code.length; i++)
- {
- if(_code[i] == "{")
- {
- if(_start == -1) _start = i;
- _count++;
- }
- else if(_code[i] == "}")
- {
-
- _end = i;
- _count--;
- if(_count == 0)
- {
- var _fn = "{" + _getVar + _code.substring(_start + 1, _end);
- var _catch = "";
- if(_code.indexOf("\"SCOPED_FUNCTION\";") > -1)
- {
- _code = _code.replace(/"SCOPED_FUNCTION";/g, " ");
- _catch = "&";
- }
-
- var _formated = "NectarCore::Type::function_t* " + _genFN +" = new NectarCore::Type::function_t([" + _catch + "](var __Nectar_THIS, NectarCore::VAR* __Nectar_VARARGS, int __Nectar_VARLENGTH) -> NectarCore::VAR" + _fn + _return + ");";
- _formated += "var " + _match[1] + "=NectarCore::VAR(NectarCore::Enum::Type::Function, " + _genFN + ");";
-
- _code = [_code.slice(0, _index), _formated, _code.slice(_end + 1)].join('');
- break;
- }
- }
- }
- _index = _code.search(_searchFN);
- }
- return _code;
-}
-
-module.exports = genMetaFunction;
\ No newline at end of file
diff --git a/compiler/native/lib/genPackage.js b/compiler/native/lib/genPackage.js
deleted file mode 100644
index aaec2b4dc..000000000
--- a/compiler/native/lib/genPackage.js
+++ /dev/null
@@ -1,17 +0,0 @@
-var _SEARCH = new RegExp(/['"]!_package *(.*)['"]/);
-
-function genPackage(from, src)
-{
- var _match = src.match(_SEARCH);
- while(_match)
- {
- var _target = _match[1].replace(/{__ARCH__}/g, os.arch());
- copyRecursiveSync(path.resolve(path.join(from, _target)), path.join(COMPILER.TMP_FOLDER, _target));
- COMPILER.PACK.push(path.join(COMPILER.TMP_FOLDER, _target));
- src = src.replace(/['"]!_package *(.*)['"]/, "");
- _match = src.match(_SEARCH);
- }
-
- return src;
-}
-module.exports = genPackage;
diff --git a/compiler/native/lib/genRequire.js b/compiler/native/lib/genRequire.js
deleted file mode 100644
index 5f0ddb61f..000000000
--- a/compiler/native/lib/genRequire.js
+++ /dev/null
@@ -1,223 +0,0 @@
-var genInclude = require("./genInclude.js");
-module.exports = genRequire;
-var fs = require("fs");
-var CACHE = {};
-
-function showModuleComment(_obj, _name)
-{
- if(Array.isArray(_obj))
- {
- for(var l = 0; l < _obj.length; l++ )
- {
- console.log("[*] " + _name + ": " + _obj[l]);
- }
- }
- else if(typeof _obj == "string")
- {
- console.log("[*] " + _name + ": " + _obj);
- }
- else if(typeof _obj == "object")
- {
- var _platform;
- if(_obj[PLATFORM]) _platform = PLATFORM;
- else if(_obj["default"]) _platform = "default";
-
- if(_obj[_platform] && typeof _obj[_platform] == "object")
- {
- var currentCompiler = COMPILER.COMPILER.split(" ")[0];
- var _compiler;
- if(_obj[_platform][currentCompiler]) _compiler = currentCompiler;
- else if(_obj[_platform]["default"]) _compiler = "default";
-
- if(_obj[_platform][_compiler]) showModuleComment(_obj[_platform][_compiler], _name);
- }
- else if(_obj[_platform]) showModuleComment(_obj[_platform], _name);
- }
-}
-
-function addModuleLib(_lib, modSource)
-{
- if(Array.isArray(_lib))
- {
- for(var l = 0; l < _lib.length; l++ )
- {
- COMPILER.LIBS += _lib[l].replace(/{__MODULE__}/g, path.resolve(modSource)).replace(/{__ARCH__}/g, os.arch()).replace(/{__EXTERN__}/g, extern) + " ";
- }
- }
- else if(typeof _lib == "string")
- {
- COMPILER.LIBS += _lib.replace(/{__MODULE__}/g, modSource).replace(/{__ARCH__}/g, os.arch()).replace(/{__EXTERN__}/g, extern) + " ";
- }
- else if(typeof _lib == "object")
- {
- var _platform;
- if(_lib[PLATFORM]) _platform = PLATFORM;
- else if(_lib["default"]) _platform = "default";
-
- if(_lib[_platform] && Array.isArray(_lib[_platform]))
- {
- addModuleLib(_lib[_platform], modSource);
- }
- if(_lib[_platform] && typeof _lib[_platform] == "object")
- {
- var currentCompiler = COMPILER.COMPILER.split(" ")[0];
- var _compiler;
- if(_lib[_platform][currentCompiler]) _compiler = currentCompiler;
- else if(_lib[_platform]["default"]) _compiler = "default";
-
- if(_lib[_platform][_compiler]) addModuleLib(_lib[_platform][_compiler], modSource);
- }
- else if(_lib[_platform]) addModuleLib(_lib[_platform], modSource);
- }
-}
-
-function genRequire(from, src)
-{
- // strip comments
- src = strip(src);
- src = genPackage(from, src);
- var _SEARCH = new RegExp(/ *require\(['"](.*?)['"]\)/);
- var seek = ["require('", "require(\""];
-
- var _match = src.match(_SEARCH);
-
- while(_match)
- {
- var addSource = _match[1];
-
- if(CACHE[addSource])
- {
- src = src.replace(_SEARCH, CACHE[addSource]);
- var _match = src.match(_SEARCH);
- }
- else
- {
-
- var modSource = "";
- var fileSource;
- if(addSource.indexOf(COMPILER.PATH) > -1)
- {
- modSource = addSource;
- }
- else
- {
- modSource = path.join(from + addSource);
- }
- var trySource = [modSource, modSource + "/" + "index.js", from + "nectar_modules/" + addSource + "/index.js", NECTAR_PATH + "/nectar_modules/" + addSource + "/index.js", from + "node_modules/" + addSource + "/index.js", NECTAR_PATH + "/node_modules/" + modSource + "/index.js", modSource + ".js",
- modSource, modSource + "/" + "index.ts", from + "nectar_modules/" + addSource + "/index.ts", NECTAR_PATH + "/nectar_modules/" + addSource + "/index.ts", from + "node_modules/" + addSource + "/index.ts", NECTAR_PATH + "/node_modules/" + modSource + "/index.ts", modSource + ".ts"];
- var newSrc = "";
- for(var i = 0; i < trySource.length; i++)
- {
- try
- {
- modSource = path.dirname(trySource[i]) + "/";
- newSrc = fs.readFileSync(trySource[i]).toString();
- fileSource = trySource[i];
-
- var pkgPath = path.join(modSource, "package.json");
- var pkgObject;
- if(fs.existsSync(pkgPath))
- {
- var pkg = fs.readFileSync(pkgPath);
- try
- {
- pkg = JSON.parse(pkg);
- pkgObject = pkg;
- if(pkg.nectar)
- {
- if(pkg.nectar.message)
- {
- showModuleComment(pkg.nectar.message, pkg.name);
- }
- if(pkg.nectar.env)
- {
- if(pkg.nectar.env.indexOf(COMPILER.ENV.name) < 0)
- {
- console.error("NectarJS:\n\n[!] module " + addSource + " doesn't support env : " + COMPILER.ENV.name + " only these : " + pkg.nectar.env);
- process.exit(1);
- }
- }
-
- if(pkg.nectar.target)
- {
- if(!COMPILER.TARGET)
- {
- console.error("NectarJS:\n\n[!] module " + addSource + " require one of these targets : " + pkg.nectar.target + ". None specified");
- process.exit(1);
- }
- else if(pkg.nectar.target.indexOf(COMPILER.TARGET) < 0)
- {
- console.error("NectarJS:\n\n[!] module " + addSource + " require one of these targets : " + pkg.nectar.target + ". " + COMPILER.TARGET + " specified");
- process.exit(1);
- }
- }
-
- if(pkg.nectar.expose)
- {
- COMPILER.EXPOSE = COMPILER.EXPOSE.concat(pkg.nectar.expose);
- COMPILER.GLOBAL = COMPILER.GLOBAL.concat(pkg.nectar.expose);
- }
-
- if(pkg.nectar.lib)
- {
- addModuleLib(pkg.nectar.lib, modSource);
- }
-
- }
- }
- catch(e)
- {
- console.log("NectarJS:\n\n[!] " + e + " -> " + pkgPath.split("/").splice(-3).join("/"))
- }
- }
-
- // EXPOSE VAR
- var _expose = {};
- if(pkgObject && pkgObject.nectar && pkgObject.nectar.expose) _expose = pkgObject.nectar.expose;
-
- // READ ONLY VAR
- if(pkgObject && pkgObject.nectar && pkgObject.nectar.read_only) COMPILER.READ_ONLY = COMPILER.READ_ONLY.concat(pkgObject.nectar.read_only);
-
- if(!CLI.cli["--no-check"]) LINT(newSrc, trySource[i], _expose);
-
- break;
- }
- catch (e) {}
- }
-
- if(newSrc.length == 0)
- {
- console.log("[!] Warning : index file of module " + addSource + " seems empty");
- }
-
- var ext = "js";
- if(fileSource && fileSource.split)
- {
- var _Ext = fileSource.split(".");
- if(_Ext.length > 1) ext = _Ext[_Ext.length - 1];
-
- if(ext == "ts") newSrc = compileTS(newSrc, fileSource);
-
- newSrc = genInclude(path.resolve(modSource) + "/", newSrc);
-
-
- var reqFN = "__MODULE_" + Math.random().toString(36).substr(2, 10);
- COMPILER.ENV.check.globals[reqFN] = false;
- CACHE[addSource] = reqFN + "()";
-
- src = src.replace(_SEARCH, reqFN + "()");
-
- newSrc = "function " + reqFN + "(){\nvar module = __NJS_Create_Object();\n" + newSrc;
- newSrc = newSrc.replace(/(module\.exports *= *.*)$/g, "$1;");
- newSrc += "return module.exports;\n}";
- newSrc = genRequire(modSource, newSrc);
-
- COMPILER.REQUIRE += newSrc + ";";
- }
- else src = src.replace(_SEARCH, "");
-
- var _match = src.match(_SEARCH);
- }
- }
- return src;
-}
diff --git a/compiler/native/lib/hoistingFunction.js b/compiler/native/lib/hoistingFunction.js
deleted file mode 100644
index c44b56fc6..000000000
--- a/compiler/native/lib/hoistingFunction.js
+++ /dev/null
@@ -1,37 +0,0 @@
-function hoistingFunction(_code)
-{
- var _hoisting = "";
- var _searchFN = new RegExp(/function +(.[a-zA-Z0-9_\-]*) *\((.*)\)/);
- var _index = _code.search(_searchFN);
- while(_index > -1)
- {
- var _count = 0;
- var _start = -1;
- var _end = -1;
- let _match = _searchFN.exec(_code);
-
- for(var i = _index; i < _code.length; i++)
- {
- if(_code[i] == "{")
- {
- if(_start == -1) _start = i;
- _count++;
- }
- else if(_code[i] == "}")
- {
- _end = i;
- _count--;
- if(_count == 0)
- {
- _hoisting += _code.substring(_index, _end + 1) + "\n";
- _code = _code.slice(0, _index) + _code.slice(_end + 1);
- break;
- }
- }
- }
- _index = _code.search(_searchFN);
- }
-
- return _hoisting + _code;
-}
-module.exports = hoistingFunction;
\ No newline at end of file
diff --git a/compiler/native/lib/replaceObjAddr.js b/compiler/native/lib/replaceObjAddr.js
deleted file mode 100644
index f9c6a56a8..000000000
--- a/compiler/native/lib/replaceObjAddr.js
+++ /dev/null
@@ -1,42 +0,0 @@
-function replaceObjAddr(_code)
-{
- var Function = [];
-
- var _searchReg = / *__Nectar_Object_Set *\( *([a-zA-Z0-9_\-" ]*) *, *([a-zA-Z0-9_\-\(\)" ]*) *, *([a-zA-Z0-9_\-" ]*) *\)/g;
- var _searchFN = / *([a-zA-Z0-9_\-" ]*) * = NectarCore::VAR\(NectarCore::Enum::Type::Function/g;
-
- var _allFN = _code.match(new RegExp(_searchFN));
- if(_allFN)
- {
- for(var i = 0; i < _allFN.length; i++)
- {
- var _localSearch = new RegExp(_searchFN);
- var _fn = _localSearch.exec(_allFN[i]);
- if(_fn);
- {
- Function.push(_fn[1]);
- }
- }
- }
-
- var _searchObject = new RegExp(_searchReg);
- var _match = _code.match(_searchObject);
- if(_match)
- {
- for(var i = 0; i < _match.length; i++)
- {
- var _localSearch = new RegExp(_searchReg);
- var _var = _localSearch.exec(_match[i]);
- if(_var);
- {
- if(_var[1] != "\"exports\"" && Function.indexOf(_var[2]) > -1)
- {
- var _getObject = new RegExp("__Nectar_Object_Get\\\(" + _var[1]+ ", " + _var[3] + "\\\)", "gm");
- _code = _code.replace(_getObject, _var[2]);
- }
- }
- }
- }
- return _code;
-}
-module.exports = replaceObjAddr;
\ No newline at end of file
diff --git a/compiler/native/nectarcpp b/compiler/native/nectarcpp
deleted file mode 160000
index f7573155a..000000000
--- a/compiler/native/nectarcpp
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit f7573155af2071ac5f279e7390a7ac273f4a7bc3
diff --git a/compiler/native/nerdcore/src/class/_meta.h b/compiler/native/nerdcore/src/class/_meta.h
new file mode 100644
index 000000000..74ba26401
--- /dev/null
+++ b/compiler/native/nerdcore/src/class/_meta.h
@@ -0,0 +1,44 @@
+/*
+ Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
+
+ 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.
+
+*/
+
+#pragma once
+#include
+
+namespace NerdCore::Class
+{
+#ifdef __NERD_ENV_ARDUINO
+ typedef uint16_t count_t;
+#else
+ typedef int count_t;
+#endif
+ class InvalidTypeException : public std::exception
+ {
+ };
+ #ifdef __NERD_ENV_ARDUINO
+ const int SMI_MAX = 32767;
+ const int SMI_MIN = -32768;
+ #else
+ const int SMI_MAX = 1073741823;
+ const int SMI_MIN = -1073741824;
+ #endif
+} // namespace NerdCore::Class
diff --git a/compiler/native/nerdcore/src/class/array.h b/compiler/native/nerdcore/src/class/array.h
new file mode 100644
index 000000000..736a0f738
--- /dev/null
+++ b/compiler/native/nerdcore/src/class/array.h
@@ -0,0 +1,438 @@
+/*
+ Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
+
+ 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.
+
+*/
+
+#pragma once
+#include "array_header.h"
+#include
+#include
+
+namespace NerdCore::Class
+{
+ // Constructors
+ Array::Array()
+ {
+ object["__proto__"] = NerdCore::Global::Array["prototype"];
+ }
+ Array::Array(NerdCore::Type::vector_t vec)
+ {
+ object["__proto__"] = NerdCore::Global::Array["prototype"];
+ value = vec;
+ }
+ Array::Array(std::initializer_list l) : value(l)
+ {
+ object["__proto__"] = NerdCore::Global::Array["prototype"];
+ }
+
+ // Methods
+ inline void Array::Delete() noexcept
+ {
+ if (--counter == 0)
+ {
+ delete this;
+ }
+ }
+ double Array::Size()
+ {
+ return value.size();
+ }
+ inline void Array::jsDelete(NerdCore::VAR _key) noexcept
+ {
+ if(_key.type == NerdCore::Enum::Type::String)
+ {
+ // TODO: if string is a number, convert to number and erase
+ }
+ else if(_key.type == NerdCore::Enum::Type::Number)
+ {
+ value[(double)_key] = NerdCore::Global::null;
+ }
+ }
+ inline void* Array::Copy() noexcept
+ {
+ counter++;
+ return this;
+ }
+ // Native cast
+ Array::operator bool() const noexcept { return true; }
+ Array::operator double() const noexcept
+ {
+ if (value.size() == 1)
+ {
+ return (double)value[0];
+ }
+ else
+ {
+ #ifdef __NERD_ENV_ARDUINO
+ return 0;
+ #else
+ return std::numeric_limits::quiet_NaN();
+ #endif
+ }
+ }
+ Array::operator int() const noexcept
+ {
+ if (value.size() == 1)
+ {
+ return (int)value[0];
+ }
+ else
+ {
+ #ifdef __NERD_ENV_ARDUINO
+ return 0;
+ #else
+ return std::numeric_limits::quiet_NaN();
+ #endif
+ }
+ }
+ Array::operator long long() const noexcept
+ {
+ if (value.size() == 1)
+ {
+ return (long long)value[0];
+ }
+ else
+ {
+ #ifdef __NERD_ENV_ARDUINO
+ return 0;
+ #else
+ return std::numeric_limits::quiet_NaN();
+ #endif
+ }
+ }
+ Array::operator std::string() const noexcept
+ {
+ auto l = value.size();
+ if (l == 0)
+ return "";
+ std::stringstream stream;
+ stream << (std::string)value[0];
+ for (auto i = 1; i < l; i++)
+ {
+ stream << "," << (std::string)value[i];
+ }
+ return stream.str();
+ }
+
+ NerdCore::VAR &Array::GetSet(std::string key)
+ {
+ #ifndef __NERD__OBJECT_VECTOR
+ // if current object[key] is null, we look for the prototypal chain
+ if(object[key].type == NerdCore::Enum::Type::Null)
+ {
+ NerdCore::VAR __proto = object["__proto__"];
+ while(__proto.type != NerdCore::Enum::Type::Null)
+ {
+ if(__proto[key].type != NerdCore::Enum::Type::Null)
+ {
+ object[key] = __proto[key];
+ break;
+ }
+ __proto = __proto["__proto__"];
+ }
+ }
+ /*
+ if(object[key].type == NerdCore::Enum::Type::Function)
+ {
+ (__NERD_FUNCTION(object[key]))->object["this"] = NerdCore::VAR(this);
+ __NERD_FUNCTION(object[key])->bind = bind;
+ }
+ */
+ return object[key];
+ #else
+ for (auto & search : object)
+ {
+ if (key.compare(search.first) == 0)
+ {
+ return search.second;
+ }
+ }
+
+ object.push_back(NerdCore::Type::pair_t(key, NerdCore::Global::null));
+
+ return object[object.size() - 1].second;
+ #endif
+ }
+
+ // Main operators
+ NerdCore::VAR const Array::operator[](int key) const
+ {
+ if (key >= 0 && key <= value.size())
+ {
+ return value.at(key);
+ }
+
+ return NerdCore::Global::null;
+ }
+
+ NerdCore::VAR &Array::operator[](NerdCore::VAR key)
+ {
+ if (key.type == NerdCore::Enum::Type::Number)
+ {
+ auto i = (int)key;
+
+ if (i < 0)
+ {
+ return NerdCore::Global::null;
+ }
+ else
+ {
+ if (i >= value.size())
+ {
+ value.resize(i + 1);
+ }
+ }
+ return value[i];
+ }
+ else
+ {
+ return GetSet(key);
+ }
+ return NerdCore::Global::null;
+ }
+
+ NerdCore::VAR &Array::operator[](int key)
+ {
+ if (key < 0)
+ {
+ return NerdCore::Global::null;
+ }
+ else
+ {
+ if (key >= value.size())
+ {
+ value.resize(key + 1);
+ }
+ }
+ return value[key];
+ }
+
+ NerdCore::VAR &Array::operator[](double key)
+ {
+ if (key < 0)
+ {
+ return NerdCore::Global::null;
+ }
+ else
+ {
+ if (key >= value.size())
+ {
+ value.resize(key + 1);
+ }
+ }
+ return value[key];
+ }
+
+ NerdCore::VAR &Array::operator[](const char* key)
+ {
+ return GetSet(key);
+ }
+
+ // Comparation operators
+ Array Array::operator!() const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Array();
+ }
+
+ // Numeric operators
+ Array Array::operator+() const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Array();
+ }
+ Array Array::operator-() const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Array();
+ }
+ Array Array::operator++(const int _v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Array();
+ }
+ Array Array::operator--(const int _v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Array();
+ }
+ Array Array::operator+(const Array &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Array();
+ }
+ Array Array::operator+=(const Array &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Array();
+ }
+ Array Array::operator-(const Array &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Array();
+ }
+ Array Array::operator-=(const Array &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Array();
+ }
+ Array Array::operator*(const Array &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Array();
+ }
+ Array Array::operator*=(const Array &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Array();
+ }
+ // TODO: "**" and "**=" operators
+ Array Array::operator/(const Array &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Array();
+ }
+ Array Array::operator/=(const Array &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Array();
+ }
+ Array Array::operator%(const Array &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Array();
+ }
+ Array Array::operator%=(const Array &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Array();
+ }
+ Array Array::operator&(const Array &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Array();
+ }
+ Array Array::operator|(const Array &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Array();
+ }
+ Array Array::operator^(const Array &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Array();
+ }
+ Array Array::operator~() const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Array();
+ }
+ Array Array::operator>>(const Array &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Array();
+ }
+ Array Array::operator<<(const Array &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Array();
+ }
+ Array Array::operator&=(const Array &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Array();
+ }
+ Array Array::operator|=(const Array &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Array();
+ }
+ Array Array::operator^=(const Array &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Array();
+ }
+ Array Array::operator>>=(const Array &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Array();
+ }
+ Array Array::operator<<=(const Array &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Array();
+ }
+ // TODO: ">>>" and ">>>=" operators
+
+
+} // namespace NerdCore::Class
diff --git a/compiler/native/nerdcore/src/class/array_header.h b/compiler/native/nerdcore/src/class/array_header.h
new file mode 100644
index 000000000..ce5f482e9
--- /dev/null
+++ b/compiler/native/nerdcore/src/class/array_header.h
@@ -0,0 +1,156 @@
+/*
+ Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
+
+ 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.
+
+*/
+
+#pragma once
+#include "_meta.h"
+
+namespace NerdCore::Class
+{
+ class Array : public virtual Base
+ {
+ public:
+ // Constructors
+ Array();
+ Array(NerdCore::Type::vector_t vec);
+
+ template
+ Array(Args ... args)
+ {
+ NerdCore::Type::vector_t _vec = {args...};
+ value = _vec;
+ }
+
+ Array(std::initializer_list l);
+
+ // Properties
+ count_t counter = 0;
+ NerdCore::Type::vector_t value;
+ NerdCore::Type::object_t object;
+ NerdCore::VAR length;
+ // Methods
+ double Size();
+ inline void Delete() noexcept;
+ inline void jsDelete(const NerdCore::VAR _key) noexcept;
+ inline void* Copy() noexcept;
+ // Native cast
+ explicit operator bool() const noexcept;
+ explicit operator double() const noexcept;
+ explicit operator int() const noexcept;
+ explicit operator long long() const noexcept;
+ explicit operator std::string() const noexcept;
+ // Main operators
+ NerdCore::VAR &GetSet(std::string key);
+ NerdCore::VAR const operator[](int key) const;
+ NerdCore::VAR &operator[](NerdCore::VAR key);
+ NerdCore::VAR &operator[](int key);
+ NerdCore::VAR &operator[](double key);
+ NerdCore::VAR &operator[](const char* key);
+
+ // Comparation operators
+ Array operator!() const;
+
+ template
+ bool operator==(const t &_v1) const { return false; }
+
+ // === emulated with __NERD_EQUAL_VALUE_AND_TYPE
+ // !== emulated with __NERD_NOT_EQUAL_VALUE_AND_TYPE
+
+ template
+ bool operator!=(const t &_v1) const { return true; }
+
+ template
+ bool operator<(const t &_v1) const { return (*this)[0] < _v1;}
+
+ template
+ bool operator<=(const t &_v1) const { return (*this)[0] <= _v1; }
+
+ template
+ bool operator>(const t &_v1) const { return (*this)[0] > _v1; }
+
+ template
+ bool operator>=(const t &_v1) const { return (*this)[0] >= _v1; }
+
+ // Numeric operators
+ Array operator+() const;
+ Array operator-() const;
+ Array operator++(const int _v1);
+ Array operator--(const int _v1);
+ Array operator+(const Array &_v1) const;
+ Array operator+=(const Array &_v1);
+ Array operator-(const Array &_v1) const;
+ Array operator-=(const Array &_v1);
+ Array operator*(const Array &_v1) const;
+ Array operator*=(const Array &_v1);
+ // TODO: "**" and "**=" operators
+ Array operator/(const Array &_v1) const;
+ Array operator/=(const Array &_v1);
+ Array operator%(const Array &_v1) const;
+ Array operator%=(const Array &_v1);
+ Array operator&(const Array &_v1) const;
+ Array operator|(const Array &_v1) const;
+ Array operator^(const Array &_v1) const;
+ Array operator~() const;
+ Array operator>>(const Array &_v1) const;
+ Array operator<<(const Array &_v1) const;
+ Array operator&=(const Array &_v1);
+ Array operator|=(const Array &_v1);
+ Array operator^=(const Array &_v1);
+ Array operator>>=(const Array &_v1);
+ Array operator<<=(const Array &_v1);
+ // TODO: ">>>" and ">>>=" operators
+
+ NerdCore::VAR __iterator(NerdCore::VAR* args, int _length) const;
+ NerdCore::VAR __unscopables(NerdCore::VAR* args, int _length) const;
+ NerdCore::VAR concat(NerdCore::VAR* args, int _length) const;
+ NerdCore::VAR copyWithin(NerdCore::VAR* args, int _length);
+ NerdCore::VAR entries(NerdCore::VAR* args, int _length) const;
+ NerdCore::VAR every(NerdCore::VAR* args, int _length) const;
+ NerdCore::VAR fill(NerdCore::VAR* args, int _length) const;
+ NerdCore::VAR filter(NerdCore::VAR* args, int _length) const;
+ NerdCore::VAR find(NerdCore::VAR* args, int _length) const;
+ NerdCore::VAR findIndex(NerdCore::VAR* args, int _length) const;
+ NerdCore::VAR flat(NerdCore::VAR* args, int _length) const;
+ NerdCore::VAR flatMap(NerdCore::VAR* args, int _length) const;
+ NerdCore::VAR forEach(NerdCore::VAR* args, int _length) const;
+ NerdCore::VAR includes(NerdCore::VAR* args, int _length) const;
+ NerdCore::VAR indexOf(NerdCore::VAR* args, int _length) const;
+ NerdCore::VAR join(NerdCore::VAR* args, int _length) const;
+ NerdCore::VAR keys(NerdCore::VAR* args, int _length) const;
+ NerdCore::VAR lastIndexOf(NerdCore::VAR* args, int _length) const;
+ NerdCore::VAR map(NerdCore::VAR* args, int _length) const;
+ NerdCore::VAR pop(NerdCore::VAR* args, int _length);
+ NerdCore::VAR push(NerdCore::VAR* args, int _length);
+ NerdCore::VAR reduce(NerdCore::VAR* args, int _length) const;
+ NerdCore::VAR reduceRight(NerdCore::VAR* args, int _length) const;
+ NerdCore::VAR reverse(NerdCore::VAR* args, int _length);
+ NerdCore::VAR shift(NerdCore::VAR* args, int _length);
+ NerdCore::VAR slice(NerdCore::VAR* args, int _length) const;
+ NerdCore::VAR some(NerdCore::VAR* args, int _length) const;
+ NerdCore::VAR sort(NerdCore::VAR* args, int _length) const;
+ NerdCore::VAR splice(NerdCore::VAR* args, int _length);
+ NerdCore::VAR toLocaleString(NerdCore::VAR* args, int _length) const;
+ NerdCore::VAR toString(NerdCore::VAR* args, int _length) const;
+ NerdCore::VAR unshift(NerdCore::VAR* args, int _length);
+ NerdCore::VAR values(NerdCore::VAR* args, int _length) const;
+ };
+} // namespace NerdCore::Class
diff --git a/compiler/native/nerdcore/src/class/base_header.h b/compiler/native/nerdcore/src/class/base_header.h
new file mode 100644
index 000000000..833ab57b6
--- /dev/null
+++ b/compiler/native/nerdcore/src/class/base_header.h
@@ -0,0 +1,47 @@
+/*
+ Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
+
+ 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.
+
+*/
+
+#pragma once
+#include "_meta.h"
+
+namespace NerdCore::Class
+{
+ class Base
+ {
+ public:
+ #ifdef __NERD_ENV_ESP32
+ virtual ~Base() { }
+ #endif
+ virtual void Delete() noexcept{};
+ virtual void* Copy() noexcept{ return nullptr; };
+ virtual explicit operator bool() const noexcept{ return true;};
+ virtual explicit operator std::string() const noexcept{ return "";};
+ virtual explicit operator int() const noexcept {return 0;};
+ virtual explicit operator double() const noexcept {return 0.0;};
+ virtual explicit operator long long() const noexcept {return 0;};
+ virtual NerdCore::VAR &operator[](NerdCore::VAR key){ return NerdCore::Global::null; };
+ virtual NerdCore::VAR &operator[](int key){ return NerdCore::Global::null; };
+ virtual NerdCore::VAR &operator[](double key){ return NerdCore::Global::null; };
+ virtual NerdCore::VAR &operator[](const char* key){ return NerdCore::Global::null; };
+ };
+}
\ No newline at end of file
diff --git a/compiler/native/nerdcore/src/class/fixed_array.h b/compiler/native/nerdcore/src/class/fixed_array.h
new file mode 100644
index 000000000..e068a24f6
--- /dev/null
+++ b/compiler/native/nerdcore/src/class/fixed_array.h
@@ -0,0 +1,401 @@
+/*
+ Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
+
+ 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.
+
+*/
+
+#pragma once
+#include "array_header.h"
+#include
+#include
+
+namespace NerdCore::Class
+{
+ // Constructors
+ FixedArray::FixedArray()
+ {
+ length = 8;
+ value = new NerdCore::VAR[8];
+ }
+ FixedArray::FixedArray(NerdCore::VAR _length)
+ {
+ length = _length;
+ value = new NerdCore::VAR[(int)_length];
+ }
+ FixedArray::FixedArray(int _length)
+ {
+ length = _length;
+ value = new NerdCore::VAR[_length];
+ }
+ FixedArray::FixedArray(NerdCore::VAR* _var, int _length)
+ {
+ length = _length;
+ value = new NerdCore::VAR[_length];
+ for(int i = 0; i < _length; i++)
+ {
+ value[i] = _var[i];
+ }
+ }
+
+ // Methods
+ inline void FixedArray::Delete() noexcept
+ {
+ if (--counter == 0)
+ {
+ delete[] value;
+ delete this;
+ }
+ }
+ inline void* FixedArray::Copy() noexcept
+ {
+ counter++;
+ return this;
+ }
+ // Native cast
+ FixedArray::operator bool() const noexcept { return true; }
+ FixedArray::operator double() const noexcept
+ {
+ if ((int)length == 1)
+ {
+ return (double)value[0];
+ }
+ else
+ {
+ #ifdef __NERD_ENV_ARDUINO
+ return 0;
+ #else
+ return std::numeric_limits::quiet_NaN();
+ #endif
+ }
+ }
+ FixedArray::operator int() const noexcept
+ {
+ if ((int)length == 1)
+ {
+ return (int)value[0];
+ }
+ else
+ {
+ #ifdef __NERD_ENV_ARDUINO
+ return 0;
+ #else
+ return std::numeric_limits::quiet_NaN();
+ #endif
+ }
+ }
+ FixedArray::operator long long() const noexcept
+ {
+ if ((int)length == 1)
+ {
+ return (long long)value[0];
+ }
+ else
+ {
+ #ifdef __NERD_ENV_ARDUINO
+ return 0;
+ #else
+ return std::numeric_limits::quiet_NaN();
+ #endif
+ }
+ }
+ FixedArray::operator std::string() const noexcept
+ {
+ auto l = (int)length;
+ std::stringstream stream;
+ stream << (std::string)value[0];
+ for (auto i = 1; i < l; i++)
+ {
+ stream << "," << (std::string)value[i];
+ }
+ return stream.str();
+ }
+ // Main operators
+ NerdCore::VAR const FixedArray::operator[](NerdCore::VAR key) const
+ {
+ if (key.type == NerdCore::Enum::Type::Number)
+ {
+ auto i = (int)key;
+ if (i >= 0 && i <= (int)length)
+ {
+ return value[i];
+ }
+ }
+
+ return NerdCore::Global::null;
+ }
+ NerdCore::VAR const FixedArray::operator[](int key) const
+ {
+ if (key >= 0 && key <= (int)length)
+ {
+ return value[key];
+ }
+
+ return NerdCore::Global::null;
+ }
+
+ NerdCore::VAR &FixedArray::operator[](NerdCore::VAR key)
+ {
+ if (key.type == NerdCore::Enum::Type::Number)
+ {
+ auto i = (int)key;
+
+ if (i < 0)
+ {
+ return NerdCore::Global::null;
+ }
+ else
+ {
+ if (i >= (int)length)
+ {
+ return NerdCore::Global::null;
+ }
+ }
+ return value[i];
+ }
+
+ return NerdCore::Global::null;
+ }
+
+ NerdCore::VAR &FixedArray::operator[](int key)
+ {
+ if (key < 0)
+ {
+ return NerdCore::Global::null;
+ }
+ else
+ {
+ if (key >= (int)length)
+ {
+ return NerdCore::Global::null;
+ }
+ }
+ return value[key];
+ }
+
+ NerdCore::VAR &FixedArray::operator[](double key)
+ {
+ if (key < 0)
+ {
+ return NerdCore::Global::null;
+ }
+ else
+ {
+ if (key >= (int)length)
+ {
+ return NerdCore::Global::null;
+ }
+ }
+ return value[(int)key];
+ }
+
+ NerdCore::VAR &FixedArray::operator[](const char* key)
+ {
+ return NerdCore::Global::null;
+ }
+
+ // Comparation operators
+ FixedArray FixedArray::operator!() const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return FixedArray();
+ }
+
+ // Numeric operators
+ FixedArray FixedArray::operator+() const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return FixedArray();
+ }
+ FixedArray FixedArray::operator-() const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return FixedArray();
+ }
+ FixedArray FixedArray::operator++(const int _v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return FixedArray();
+ }
+ FixedArray FixedArray::operator--(const int _v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return FixedArray();
+ }
+ FixedArray FixedArray::operator+(const FixedArray &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return FixedArray();
+ }
+ FixedArray FixedArray::operator+=(const FixedArray &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return FixedArray();
+ }
+ FixedArray FixedArray::operator-(const FixedArray &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return FixedArray();
+ }
+ FixedArray FixedArray::operator-=(const FixedArray &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return FixedArray();
+ }
+ FixedArray FixedArray::operator*(const FixedArray &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return FixedArray();
+ }
+ FixedArray FixedArray::operator*=(const FixedArray &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return FixedArray();
+ }
+ // TODO: "**" and "**=" operators
+ FixedArray FixedArray::operator/(const FixedArray &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return FixedArray();
+ }
+ FixedArray FixedArray::operator/=(const FixedArray &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return FixedArray();
+ }
+ FixedArray FixedArray::operator%(const FixedArray &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return FixedArray();
+ }
+ FixedArray FixedArray::operator%=(const FixedArray &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return FixedArray();
+ }
+ FixedArray FixedArray::operator&(const FixedArray &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return FixedArray();
+ }
+ FixedArray FixedArray::operator|(const FixedArray &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return FixedArray();
+ }
+ FixedArray FixedArray::operator^(const FixedArray &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return FixedArray();
+ }
+ FixedArray FixedArray::operator~() const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return FixedArray();
+ }
+ FixedArray FixedArray::operator>>(const FixedArray &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return FixedArray();
+ }
+ FixedArray FixedArray::operator<<(const FixedArray &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return FixedArray();
+ }
+ FixedArray FixedArray::operator&=(const FixedArray &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return FixedArray();
+ }
+ FixedArray FixedArray::operator|=(const FixedArray &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return FixedArray();
+ }
+ FixedArray FixedArray::operator^=(const FixedArray &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return FixedArray();
+ }
+ FixedArray FixedArray::operator>>=(const FixedArray &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return FixedArray();
+ }
+ FixedArray FixedArray::operator<<=(const FixedArray &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return FixedArray();
+ }
+ // TODO: ">>>" and ">>>=" operators
+
+} // namespace NerdCore::Class
diff --git a/compiler/native/nerdcore/src/class/fixed_array_header.h b/compiler/native/nerdcore/src/class/fixed_array_header.h
new file mode 100644
index 000000000..174e759c2
--- /dev/null
+++ b/compiler/native/nerdcore/src/class/fixed_array_header.h
@@ -0,0 +1,111 @@
+/*
+ Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
+
+ 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.
+
+*/
+
+#pragma once
+#include "_meta.h"
+
+namespace NerdCore::Class
+{
+ class FixedArray : public virtual Base
+ {
+ public:
+ // Constructors
+ FixedArray();
+ FixedArray(NerdCore::VAR length);
+ FixedArray(int length);
+ FixedArray(NerdCore::VAR* value, int length);
+ // Properties
+ count_t counter = 0;
+ NerdCore::VAR length;
+ NerdCore::VAR* value;
+ // Methods
+ inline void Delete() noexcept;
+ inline void* Copy() noexcept;
+ // Native cast
+ explicit operator bool() const noexcept;
+ explicit operator double() const noexcept;
+ explicit operator int() const noexcept;
+ explicit operator long long() const noexcept;
+ explicit operator std::string() const noexcept;
+ // Main operators
+ NerdCore::VAR const operator[](NerdCore::VAR key) const;
+ NerdCore::VAR const operator[](int key) const;
+ NerdCore::VAR &operator[](NerdCore::VAR key);
+ NerdCore::VAR &operator[](int key);
+ NerdCore::VAR &operator[](double key);
+ NerdCore::VAR &operator[](const char* key);
+
+ // Comparation operators
+ FixedArray operator!() const;
+
+ template
+ bool operator==(const t &_v1) const { return false; }
+
+ // === emulated with __NERD_EQUAL_VALUE_AND_TYPE
+ // !== emulated with __NERD_NOT_EQUAL_VALUE_AND_TYPE
+
+ template
+ bool operator!=(const t &_v1) const { return true; }
+
+ template
+ bool operator<(const t &_v1) const { return (*this)[0] < _v1;}
+
+ template
+ bool operator<=(const t &_v1) const { return (*this)[0] <= _v1; }
+
+ template
+ bool operator>(const t &_v1) const { return (*this)[0] > _v1; }
+
+ template
+ bool operator>=(const t &_v1) const { return (*this)[0] >= _v1; }
+
+ // Numeric operators
+ FixedArray operator+() const;
+ FixedArray operator-() const;
+ FixedArray operator++(const int _v1);
+ FixedArray operator--(const int _v1);
+ FixedArray operator+(const FixedArray &_v1) const;
+ FixedArray operator+=(const FixedArray &_v1);
+ FixedArray operator-(const FixedArray &_v1) const;
+ FixedArray operator-=(const FixedArray &_v1);
+ FixedArray operator*(const FixedArray &_v1) const;
+ FixedArray operator*=(const FixedArray &_v1);
+ // TODO: "**" and "**=" operators
+ FixedArray operator/(const FixedArray &_v1) const;
+ FixedArray operator/=(const FixedArray &_v1);
+ FixedArray operator%(const FixedArray &_v1) const;
+ FixedArray operator%=(const FixedArray &_v1);
+ FixedArray operator&(const FixedArray &_v1) const;
+ FixedArray operator|(const FixedArray &_v1) const;
+ FixedArray operator^(const FixedArray &_v1) const;
+ FixedArray operator~() const;
+ FixedArray operator>>(const FixedArray &_v1) const;
+ FixedArray operator<<(const FixedArray &_v1) const;
+ FixedArray operator&=(const FixedArray &_v1);
+ FixedArray operator|=(const FixedArray &_v1);
+ FixedArray operator^=(const FixedArray &_v1);
+ FixedArray operator>>=(const FixedArray &_v1);
+ FixedArray operator<<=(const FixedArray &_v1);
+ // TODO: ">>>" and ">>>=" operators
+ };
+} // namespace NerdCore::Class
diff --git a/compiler/native/nerdcore/src/class/function.h b/compiler/native/nerdcore/src/class/function.h
new file mode 100644
index 000000000..3390b2288
--- /dev/null
+++ b/compiler/native/nerdcore/src/class/function.h
@@ -0,0 +1,410 @@
+/*
+ Copyright (c) 2022 NerdLang - Adrien THIERRY and contributors
+
+ 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.
+
+*/
+
+#pragma once
+#include "function_header.h"
+#include
+#include
+
+namespace NerdCore::Class
+{
+ // Constructors
+ Function::Function()
+ {
+ (*this)["prototype"] = new NerdCore::Class::Object();
+ }
+ Function::Function(void *val)
+ {
+ counter++;
+ value = (NerdCore::Type::function_t*)val;
+ if((*this)["prototype"].type == NerdCore::Enum::Type::Null)
+ {
+ (*this)["prototype"] = new NerdCore::Class::Object();
+ }
+ }
+ Function::Function(void *val, NerdCore::VAR __this)
+ {
+ counter++;
+ (*this)["this"] = __this;
+ value = (NerdCore::Type::function_t*)val;
+ if((*this)["prototype"].type == NerdCore::Enum::Type::Null)
+ {
+ (*this)["prototype"] = new NerdCore::Class::Object();
+ }
+ }
+ // Methods
+ inline void Function::Delete() noexcept
+ {
+ if (--counter < 1)
+ {
+ delete (NerdCore::Type::function_t*)value;
+ delete this;
+ }
+ }
+ inline void Function::jsDelete(const std::string _key) noexcept
+ {
+
+ }
+ inline void* Function::Copy() noexcept
+ {
+ counter++;
+ return this;
+ }
+
+ // Main operators
+ NerdCore::VAR const Function::operator[](NerdCore::VAR key) const
+ {
+ return NerdCore::Global::null;
+ }
+
+ #ifndef __NERD__OBJECT_VECTOR
+ NerdCore::VAR &Function::operator[](NerdCore::VAR key)
+ {
+ /*
+ if(hasLazy && LazyRTM.count(key) && !object.count(key))
+ {
+ object[key] = LazyRTM[key];
+ }
+ */
+ return object[key];
+ }
+ #else
+ NerdCore::VAR &Function::operator[](NerdCore::VAR key)
+ {
+ std::string _str = ((std::string)key);
+ NerdCore::Type::StringView _sview = _str;
+
+ if (key.type == NerdCore::Enum::Type::Number)
+ {
+ auto i = (int)key;
+
+ if (i < 0)
+ {
+ return NerdCore::Global::null;
+ }
+ else
+ {
+ if (i >= object.size())
+ {
+ object.reserve(i + 1);
+ object.resize(i + 1);
+ }
+ }
+ return object[i].second;
+ }
+
+ for (auto & search : object)
+ {
+ if (_sview.compare(search.first) == 0)
+ {
+ return search.second;
+ }
+ }
+
+ object.push_back(NerdCore::Type::pair_t(_str, NerdCore::Global::null));
+
+ return object[object.size() - 1].second;
+ }
+ #endif
+
+ #ifndef __NERD__OBJECT_VECTOR
+ NerdCore::VAR &Function::operator[](int key)
+ {
+ std::string _str = std::to_string(key);
+ NerdCore::Type::StringView _sview = _str;
+
+ return object[_str];
+ }
+ #else
+ NerdCore::VAR &Function::operator[](int key)
+ {
+ std::string _str = std::to_string(key);
+ NerdCore::Type::StringView _sview = _str;
+
+ for (auto & search : object)
+ {
+ if (_sview.compare(search.first) == 0)
+ {
+ return search.second;
+ }
+ }
+
+ object.push_back(NerdCore::Type::pair_t(_str, NerdCore::Global::null));
+
+
+ return object[object.size() - 1].second;
+ }
+ #endif
+
+ #ifndef __NERD__OBJECT_VECTOR
+ NerdCore::VAR &Function::operator[](double key)
+ {
+ std::string _str = std::to_string(key);
+ NerdCore::Type::StringView _sview = _str;
+
+ return object[_str];
+ }
+ #else
+ NerdCore::VAR &Function::operator[](double key)
+ {
+ std::string _str = std::to_string(key);
+ NerdCore::Type::StringView _sview = _str;
+
+ for (auto & search : object)
+ {
+ if (_sview.compare(search.first) == 0)
+ {
+ return search.second;
+ }
+ }
+
+ object.push_back(NerdCore::Type::pair_t(_str, NerdCore::Global::null));
+
+ return object[object.size() - 1].second;
+ }
+ #endif
+
+ #ifndef __NERD__OBJECT_VECTOR
+ NerdCore::VAR &Function::operator[](const char* key)
+ {
+ /*
+ if(hasLazy && LazyRTM.count(key) && !object.count(key))
+ {
+ object[key] = LazyRTM[key];
+ }
+ */
+ return object[key];
+ }
+ #else
+ NerdCore::VAR &Function::operator[](const char* key)
+ {
+ std::string _str = key;
+ NerdCore::Type::StringView _sview = _str;
+
+ for (auto & search : object)
+ {
+ if (_sview.compare(search.first) == 0)
+ {
+ return search.second;
+ }
+ }
+
+ object.push_back(NerdCore::Type::pair_t(_str, NerdCore::Global::null));
+
+
+ return object[object.size() - 1].second;
+ }
+ #endif
+
+ // Comparation operators
+ NerdCore::VAR Function::operator!() const
+ {
+ return __NERD_Boolean_FALSE;
+ }
+ bool Function::operator==(const Function &_v1) const { return false; }
+ // === emulated with __NERD_EQUAL_VALUE_AND_TYPE
+ // !== emulated with __NERD_NOT_EQUAL_VALUE_AND_TYPE
+ bool Function::operator!=(const Function &_v1) const { return true; }
+ bool Function::operator<(const Function &_v1) const { return false; }
+ bool Function::operator<=(const Function &_v1) const { return true; }
+ bool Function::operator>(const Function &_v1) const { return false; }
+ bool Function::operator>=(const Function &_v1) const { return true; }
+ // Numeric operators
+ Function Function::operator+() const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Function();
+ }
+ Function Function::operator-() const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Function();
+ }
+ Function Function::operator++(const int _v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Function();
+ }
+ Function Function::operator--(const int _v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Function();
+ }
+ Function Function::operator+(const Function &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Function();
+ }
+ Function Function::operator+=(const Function &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Function();
+ }
+ Function Function::operator-(const Function &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Function();
+ }
+ Function Function::operator-=(const Function &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Function();
+ }
+ Function Function::operator*(const Function &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Function();
+ }
+ Function Function::operator*=(const Function &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Function();
+ }
+ // TODO: "**" and "**=" operators
+ Function Function::operator/(const Function &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Function();
+ }
+ Function Function::operator/=(const Function &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Function();
+ }
+ Function Function::operator%(const Function &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Function();
+ }
+ Function Function::operator%=(const Function &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Function();
+ }
+ Function Function::operator&(const Function &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Function();
+ }
+ Function Function::operator|(const Function &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Function();
+ }
+ Function Function::operator^(const Function &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Function();
+ }
+ Function Function::operator~() const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Function();
+ }
+ Function Function::operator>>(const Function &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Function();
+ }
+ Function Function::operator<<(const Function &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Function();
+ }
+ Function Function::operator&=(const Function &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Function();
+ }
+ Function Function::operator|=(const Function &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Function();
+ }
+ Function Function::operator^=(const Function &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Function();
+ }
+ Function Function::operator>>=(const Function &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Function();
+ }
+ Function Function::operator<<=(const Function &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Function();
+ }
+ // TODO: ">>>" and ">>>=" operators
+} // namespace NerdCore::Class
diff --git a/compiler/native/nerdcore/src/class/function_header.h b/compiler/native/nerdcore/src/class/function_header.h
new file mode 100644
index 000000000..7ec4cc959
--- /dev/null
+++ b/compiler/native/nerdcore/src/class/function_header.h
@@ -0,0 +1,151 @@
+/*
+ Copyright (c) 2022 NerdLang - Adrien THIERRY and contributors
+
+ 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.
+
+*/
+
+#pragma once
+#include "_meta.h"
+
+namespace NerdCore::Class
+{
+ class Function : public virtual Base
+ {
+ public:
+ // Constructors
+ Function();
+ Function(void* val);
+ Function(void* val, NerdCore::VAR __this);
+ // Properties
+ count_t counter = 0;
+
+ NerdCore::Type::function_t* value = nullptr;
+ NerdCore::Type::object_t object;
+ NerdCore::VAR This;
+ //void* bind = nullptr;
+ // Methods
+ inline void Delete() noexcept;
+ inline void jsDelete(std::string _key) noexcept;
+ inline void* Copy() noexcept;
+
+ inline NerdCore::VAR Call(NerdCore::VAR __NERD_THIS, NerdCore::VAR* _args, int i)
+ {
+ #ifndef __NERD__OBJECT_VECTOR
+ if(__NERD_THIS.type == NerdCore::Enum::Type::Null)
+ {
+ return std::invoke((*static_cast(value)), This, _args, i);
+ }
+ else
+ {
+ return std::invoke((*static_cast(value)), __NERD_THIS, _args, i);
+ }
+ #else
+ return (*static_cast(value))(__NERD_THIS, _args, i);
+ #endif
+ }
+
+ template
+ NerdCore::VAR operator()(NerdCore::VAR __NERD_THIS, Args... args)
+ {
+ NerdCore::VAR _args[] = {args...};
+ int i = sizeof...(args);
+ #ifndef __NERD__OBJECT_VECTOR
+ if(__NERD_THIS.type == NerdCore::Enum::Type::Null)
+ {
+ return std::invoke((*static_cast(value)), This, _args, i);
+ }
+ else
+ {
+ return std::invoke((*static_cast(value)), __NERD_THIS, _args, i);
+ }
+ #else
+ return (*static_cast(value))(__NERD_THIS, _args, i);
+ #endif
+ }
+
+ template
+ NerdCore::VAR New(NerdCore::VAR __NERD_THIS, Args... args)
+ {
+
+ NerdCore::VAR _args[] = {args...};
+ int i = sizeof...(args);
+
+ NerdCore::VAR _this = new NerdCore::Class::Object(); //__NERD_Object_Clone((*this)["this"]);
+ if(_this.type == NerdCore::Enum::Type::Null) _this = new NerdCore::Class::Object();
+
+ //((NerdCore::Class::Object*)_this.data.ptr)->bind = bind;
+ NerdCore::VAR _return = this->Call(_this, _args, i);
+ if(_return.type == NerdCore::Enum::Type::Object)
+ {
+ _this = _return;
+ }
+ _this["__proto__"] = object["prototype"];
+ return _this;
+
+ }
+
+
+ // Main operators
+ NerdCore::VAR const operator[](NerdCore::VAR key) const;
+ NerdCore::VAR &operator[](NerdCore::VAR key);
+ NerdCore::VAR &operator[](int key);
+ NerdCore::VAR &operator[](double key);
+ NerdCore::VAR &operator[](const char* key);
+
+ // Comparation operators
+ NerdCore::VAR operator!() const;
+ bool operator==(const Function &_v1) const;
+ // === emulated with __NERD_EQUAL_VALUE_AND_TYPE
+ // !== emulated with __NERD_NOT_EQUAL_VALUE_AND_TYPE
+ bool operator!=(const Function &_v1) const;
+ bool operator<(const Function &_v1) const;
+ bool operator<=(const Function &_v1) const;
+ bool operator>(const Function &_v1) const;
+ bool operator>=(const Function &_v1) const;
+ // Numeric operators
+ Function operator+() const;
+ Function operator-() const;
+ Function operator++(const int _v1);
+ Function operator--(const int _v1);
+ Function operator+(const Function &_v1) const;
+ Function operator+=(const Function &_v1);
+ Function operator-(const Function &_v1) const;
+ Function operator-=(const Function &_v1);
+ Function operator*(const Function &_v1) const;
+ Function operator*=(const Function &_v1);
+ // TODO: "**" and "**=" operators
+ Function operator/(const Function &_v1) const;
+ Function operator/=(const Function &_v1);
+ Function operator%(const Function &_v1) const;
+ Function operator%=(const Function &_v1);
+ Function operator&(const Function &_v1) const;
+ Function operator|(const Function &_v1) const;
+ Function operator^(const Function &_v1) const;
+ Function operator~() const;
+ Function operator>>(const Function &_v1) const;
+ Function operator<<(const Function &_v1) const;
+ Function operator&=(const Function &_v1);
+ Function operator|=(const Function &_v1);
+ Function operator^=(const Function &_v1);
+ Function operator>>=(const Function &_v1);
+ Function operator<<=(const Function &_v1);
+ // TODO: ">>>" and ">>>=" operators
+ };
+} // namespace NerdCore::Class
\ No newline at end of file
diff --git a/compiler/native/nerdcore/src/class/native.h b/compiler/native/nerdcore/src/class/native.h
new file mode 100644
index 000000000..63f4debcd
--- /dev/null
+++ b/compiler/native/nerdcore/src/class/native.h
@@ -0,0 +1,301 @@
+/*
+ Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
+
+ 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.
+
+*/
+
+#pragma once
+#include "native_header.h"
+#include
+#include
+
+namespace NerdCore::Class
+{
+ // Constructors
+ Native::Native() {}
+ Native::Native(void *val)
+ {
+ value = val;
+ }
+ // Methods
+ inline void Native::Delete() noexcept
+ {
+ if (--counter < 1)
+ {
+ if((*this)["__NERD_On_Destroy"]) (*this)["__NERD_On_Destroy"](NerdCore::Global::null);
+ delete this;
+ }
+ }
+ inline void* Native::Copy() noexcept
+ {
+ counter++;
+ return this;
+ }
+ // Native cast
+ Native::operator bool() const noexcept { return true; }
+ Native::operator double() const noexcept
+ {
+ #ifdef __NERD_ENV_ARDUINO
+ return 0;
+ #else
+ return std::numeric_limits::quiet_NaN();
+ #endif
+ }
+ Native::operator int() const noexcept
+ {
+ #ifdef __NERD_ENV_ARDUINO
+ return 0;
+ #else
+ return std::numeric_limits::quiet_NaN();
+ #endif
+ }
+ Native::operator long long() const noexcept
+ {
+ #ifdef __NERD_ENV_ARDUINO
+ return 0;
+ #else
+ return std::numeric_limits::quiet_NaN();
+ #endif
+ }
+ Native::operator std::string() const noexcept
+ {
+ return "[native code]";
+ }
+ // Main operators
+ NerdCore::VAR const Native::operator[](NerdCore::VAR key) const
+ {
+ return NerdCore::Global::null;
+ }
+ NerdCore::VAR &Native::operator[](NerdCore::VAR key)
+ {
+ return NerdCore::Global::null;
+ }
+
+ NerdCore::VAR &Native::operator[](int key)
+ {
+ return NerdCore::Global::null;
+ }
+
+ NerdCore::VAR &Native::operator[](double key)
+ {
+ return NerdCore::Global::null;
+ }
+
+
+ NerdCore::VAR &Native::operator[](const char* key)
+ {
+ return NerdCore::Global::null;
+ }
+
+ // Comparation operators
+ Native Native::operator!() const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Native();
+ }
+ bool Native::operator==(const Native &_v1) const { return false; }
+ // === emulated with __NERD_EQUAL_VALUE_AND_TYPE
+ // !== emulated with __NERD_NOT_EQUAL_VALUE_AND_TYPE
+ bool Native::operator!=(const Native &_v1) const { return true; }
+ bool Native::operator<(const Native &_v1) const { return false; }
+ bool Native::operator<=(const Native &_v1) const { return true; }
+ bool Native::operator>(const Native &_v1) const { return false; }
+ bool Native::operator>=(const Native &_v1) const { return true; }
+ // Numeric operators
+ Native Native::operator+() const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Native();
+ }
+ Native Native::operator-() const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Native();
+ }
+ Native Native::operator++(const int _v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Native();
+ }
+ Native Native::operator--(const int _v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Native();
+ }
+ Native Native::operator+(const Native &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Native();
+ }
+ Native Native::operator+=(const Native &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Native();
+ }
+ Native Native::operator-(const Native &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Native();
+ }
+ Native Native::operator-=(const Native &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Native();
+ }
+ Native Native::operator*(const Native &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Native();
+ }
+ Native Native::operator*=(const Native &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Native();
+ }
+ // TODO: "**" and "**=" operators
+ Native Native::operator/(const Native &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Native();
+ }
+ Native Native::operator/=(const Native &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Native();
+ }
+ Native Native::operator%(const Native &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Native();
+ }
+ Native Native::operator%=(const Native &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Native();
+ }
+ Native Native::operator&(const Native &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Native();
+ }
+ Native Native::operator|(const Native &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Native();
+ }
+ Native Native::operator^(const Native &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Native();
+ }
+ Native Native::operator~() const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Native();
+ }
+ Native Native::operator>>(const Native &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Native();
+ }
+ Native Native::operator<<(const Native &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Native();
+ }
+ Native Native::operator&=(const Native &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Native();
+ }
+ Native Native::operator|=(const Native &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Native();
+ }
+ Native Native::operator^=(const Native &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Native();
+ }
+ Native Native::operator>>=(const Native &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Native();
+ }
+ Native Native::operator<<=(const Native &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Native();
+ }
+ // TODO: ">>>" and ">>>=" operators
+} // namespace NerdCore::Class
diff --git a/compiler/native/nerdcore/src/class/native_header.h b/compiler/native/nerdcore/src/class/native_header.h
new file mode 100644
index 000000000..cdaa099b8
--- /dev/null
+++ b/compiler/native/nerdcore/src/class/native_header.h
@@ -0,0 +1,94 @@
+/*
+ Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
+
+ 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.
+
+*/
+
+#pragma once
+#include "_meta.h"
+
+namespace NerdCore::Class
+{
+ class Native : public virtual Base
+ {
+ public:
+ // Constructors
+ Native();
+ Native(void* val);
+ // Properties
+ count_t counter = 1;
+ int length = 0;
+ void* value = nullptr;
+ // Methods
+ inline void Delete() noexcept;
+ inline void* Copy() noexcept;
+ // Native cast
+ explicit operator bool() const noexcept;
+ explicit operator double() const noexcept;
+ explicit operator int() const noexcept;
+ explicit operator long long() const noexcept;
+ explicit operator std::string() const noexcept;
+ // Main operators
+ NerdCore::VAR const operator[](NerdCore::VAR key) const;
+ NerdCore::VAR &operator[](NerdCore::VAR key);
+ NerdCore::VAR &operator[](int key);
+ NerdCore::VAR &operator[](double key);
+ NerdCore::VAR &operator[](const char* key);
+
+ // Comparation operators
+ Native operator!() const;
+ bool operator==(const Native &_v1) const;
+ // === emulated with __NERD_EQUAL_VALUE_AND_TYPE
+ // !== emulated with __NERD_NOT_EQUAL_VALUE_AND_TYPE
+ bool operator!=(const Native &_v1) const;
+ bool operator<(const Native &_v1) const;
+ bool operator<=(const Native &_v1) const;
+ bool operator>(const Native &_v1) const;
+ bool operator>=(const Native &_v1) const;
+ // Numeric operators
+ Native operator+() const;
+ Native operator-() const;
+ Native operator++(const int _v1);
+ Native operator--(const int _v1);
+ Native operator+(const Native &_v1) const;
+ Native operator+=(const Native &_v1);
+ Native operator-(const Native &_v1) const;
+ Native operator-=(const Native &_v1);
+ Native operator*(const Native &_v1) const;
+ Native operator*=(const Native &_v1);
+ // TODO: "**" and "**=" operators
+ Native operator/(const Native &_v1) const;
+ Native operator/=(const Native &_v1);
+ Native operator%(const Native &_v1) const;
+ Native operator%=(const Native &_v1);
+ Native operator&(const Native &_v1) const;
+ Native operator|(const Native &_v1) const;
+ Native operator^(const Native &_v1) const;
+ Native operator~() const;
+ Native operator>>(const Native &_v1) const;
+ Native operator<<(const Native &_v1) const;
+ Native operator&=(const Native &_v1);
+ Native operator|=(const Native &_v1);
+ Native operator^=(const Native &_v1);
+ Native operator>>=(const Native &_v1);
+ Native operator<<=(const Native &_v1);
+ // TODO: ">>>" and ">>>=" operators
+ };
+} // namespace NerdCore::Class
diff --git a/compiler/native/nerdcore/src/class/native_tpl_header.h b/compiler/native/nerdcore/src/class/native_tpl_header.h
new file mode 100644
index 000000000..858ddd054
--- /dev/null
+++ b/compiler/native/nerdcore/src/class/native_tpl_header.h
@@ -0,0 +1,359 @@
+/*
+ Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
+
+ 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.
+
+*/
+
+#pragma once
+#include "_meta.h"
+
+
+namespace NerdCore::Class
+{
+ template
+ class NativeTPL : public virtual Base
+ {
+
+ private:
+ inline void internalDelete()
+ {
+ if(is_ptr)
+ {
+ delete value;
+ }
+ }
+ public:
+ // Constructors
+ bool is_ptr = true;
+ int length = 0;
+ std::string type;
+
+ NativeTPL(T val)
+ {
+ is_ptr = true;
+ value = val;
+
+ type = "undef";
+ }
+ NativeTPL(T val, const char str[])
+ {
+ is_ptr = true;
+ type = str;
+ value = val;
+ }
+ NativeTPL(T val, bool isPtr)
+ {
+ is_ptr = isPtr;
+ value = val;
+ type = "undef";
+ }
+ NativeTPL(T val, const char str[], bool isPtr)
+ {
+ is_ptr = isPtr;
+ value = val;
+ type = str;
+ }
+ // Properties
+ count_t counter = 1;
+ T value;
+ NerdCore::Type::object_t object;
+ // Methods
+
+ inline void Delete() noexcept
+ {
+ if (--counter == 0)
+ {
+ internalDelete();
+ delete this;
+ }
+ }
+
+ inline void* Copy() noexcept
+ {
+ counter++;
+ return this;
+ }
+
+ template
+ const inline T operator()(Cast& c) const
+ {
+ static_assert(std::is_same::value, "Casting must be same as NativeType");
+
+ return value;
+ }
+
+ inline T operator()() const
+ {
+ return value;
+ }
+
+ operator bool() const noexcept { return true; }
+ operator double() const noexcept
+ {
+ #ifdef __NERD_ENV_ARDUINO
+ return 0;
+ #else
+ return std::numeric_limits::quiet_NaN();
+ #endif
+ }
+ operator int() const noexcept
+ {
+ #ifdef __NERD_ENV_ARDUINO
+ return 0;
+ #else
+ return std::numeric_limits::quiet_NaN();
+ #endif
+ }
+ operator long long() const noexcept
+ {
+ #ifdef __NERD_ENV_ARDUINO
+ return 0;
+ #else
+ return std::numeric_limits::quiet_NaN();
+ #endif
+ }
+ operator std::string() const noexcept
+ {
+ return std::string("[native ") + type + std::string("]");
+ }
+
+ // Main operators
+ NerdCore::VAR const operator[](NerdCore::VAR key) const
+ {
+ return NerdCore::Global::null;
+ }
+ NerdCore::VAR &operator[](NerdCore::VAR key)
+ {
+ return NerdCore::Global::null;
+ }
+
+ NerdCore::VAR &operator[](int key)
+ {
+ return NerdCore::Global::null;
+ }
+
+ NerdCore::VAR &operator[](double key)
+ {
+ return NerdCore::Global::null;
+ }
+
+
+ NerdCore::VAR &operator[](const char* key)
+ {
+ return NerdCore::Global::null;
+ }
+
+ // Comparation operators
+ NativeTPL operator!() const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NativeTPL();
+ }
+ bool operator==(const NativeTPL &_v1) const { return false; }
+ // === emulated with __NERD_EQUAL_VALUE_AND_TYPE
+ // !== emulated with __NERD_NOT_EQUAL_VALUE_AND_TYPE
+ bool operator!=(const NativeTPL &_v1) const { return true; }
+ bool operator<(const NativeTPL &_v1) const { return false; }
+ bool operator<=(const NativeTPL &_v1) const { return true; }
+ bool operator>(const NativeTPL &_v1) const { return false; }
+ bool operator>=(const NativeTPL &_v1) const { return true; }
+ // Numeric operators
+ NativeTPL operator+() const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NativeTPL();
+ }
+ NativeTPL operator-() const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NativeTPL();
+ }
+ NativeTPL operator++(const int _v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NativeTPL();
+ }
+ NativeTPL operator--(const int _v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NativeTPL();
+ }
+ NativeTPL operator+(const NativeTPL &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NativeTPL();
+ }
+ NativeTPL operator+=(const NativeTPL &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NativeTPL();
+ }
+ NativeTPL operator-(const NativeTPL &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NativeTPL();
+ }
+ NativeTPL operator-=(const NativeTPL &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NativeTPL();
+ }
+ NativeTPL operator*(const NativeTPL &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NativeTPL();
+ }
+ NativeTPL operator*=(const NativeTPL &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NativeTPL();
+ }
+ // TODO: "**" and "**=" operators
+ NativeTPL operator/(const NativeTPL &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NativeTPL();
+ }
+ NativeTPL operator/=(const NativeTPL &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NativeTPL();
+ }
+ NativeTPL operator%(const NativeTPL &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NativeTPL();
+ }
+ NativeTPL operator%=(const NativeTPL &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NativeTPL();
+ }
+ NativeTPL operator&(const NativeTPL &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NativeTPL();
+ }
+ NativeTPL operator|(const NativeTPL &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NativeTPL();
+ }
+ NativeTPL operator^(const NativeTPL &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NativeTPL();
+ }
+ NativeTPL operator~() const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NativeTPL();
+ }
+ NativeTPL operator>>(const NativeTPL &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NativeTPL();
+ }
+ NativeTPL operator<<(const NativeTPL &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NativeTPL();
+ }
+ NativeTPL operator&=(const NativeTPL &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NativeTPL();
+ }
+ NativeTPL operator|=(const NativeTPL &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NativeTPL();
+ }
+ NativeTPL operator^=(const NativeTPL &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NativeTPL();
+ }
+ NativeTPL operator>>=(const NativeTPL &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NativeTPL();
+ }
+ NativeTPL operator<<=(const NativeTPL &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NativeTPL();
+ }
+ // TODO: ">>>" and ">>>=" operators
+
+ };
+} // namespace NerdCore::Class
diff --git a/compiler/native/nerdcore/src/class/number.h b/compiler/native/nerdcore/src/class/number.h
new file mode 100644
index 000000000..19e3b7c22
--- /dev/null
+++ b/compiler/native/nerdcore/src/class/number.h
@@ -0,0 +1,27 @@
+/*
+ Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
+
+ 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.
+
+*/
+
+namespace NerdCore::Class::NUMBER
+{
+
+}
diff --git a/compiler/native/nerdcore/src/class/number_header.h b/compiler/native/nerdcore/src/class/number_header.h
new file mode 100644
index 000000000..c9a134f2f
--- /dev/null
+++ b/compiler/native/nerdcore/src/class/number_header.h
@@ -0,0 +1,27 @@
+/*
+ Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
+
+ 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.
+
+*/
+
+namespace NerdCore::Class::NUMBER
+{
+
+}
diff --git a/compiler/native/nerdcore/src/class/object.h b/compiler/native/nerdcore/src/class/object.h
new file mode 100644
index 000000000..a02c0321a
--- /dev/null
+++ b/compiler/native/nerdcore/src/class/object.h
@@ -0,0 +1,386 @@
+/*
+ Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
+
+ 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.
+
+*/
+
+#pragma once
+#include "object_header.h"
+#include
+
+namespace NerdCore::Class
+{
+ NerdCore::VAR __proxy;
+ // Constructors
+ Object::Object() { }
+
+ /*
+ Object::Object(const char* _key, NerdCore::VAR _value)
+ {
+ object[_key] = _value;
+ }
+ */
+ /*
+ Object::Object(NerdCore::VAR _obj)
+ {
+ object = ((NerdCore::Class::Object*)_obj.data.ptr)->object;
+ }
+ */
+
+ Object::Object(NerdCore::Type::object_t obj)
+ {
+ object = obj;
+ }
+
+ Object::Object(std::initializer_list obj)
+ {
+ for (NerdCore::Type::pair_t p : obj)
+ {
+ object[p.first] = p.second;
+ }
+ }
+
+ // Methods
+ double Object::Size()
+ {
+ return object.size();
+ }
+
+ inline void Object::Delete() noexcept
+ {
+ if (--counter < 1)
+ {
+ delete this;
+ }
+ }
+ inline void Object::jsDelete(const std::string _key) noexcept
+ {
+ #ifndef __NERD__OBJECT_VECTOR
+ object.erase(_key);
+ #else
+ for (NerdCore::Type::object_t::iterator it = object.begin() ; it != object.end(); ++it)
+ {
+ if (_key.compare(it->first) == 0)
+ {
+ object.erase(it);
+ return;
+ }
+ }
+ #endif
+ }
+ inline void* Object::Copy() noexcept
+ {
+ counter++;
+ return this;
+ }
+ // Native cast
+ Object::operator bool() const noexcept { return true; }
+ Object::operator double() const noexcept
+ {
+ #ifdef __NERD_ENV_ARDUINO
+ return 0;
+ #else
+ return std::numeric_limits::quiet_NaN();
+ #endif
+ }
+ Object::operator int() const noexcept
+ {
+ #ifdef __NERD_ENV_ARDUINO
+ return 0;
+ #else
+ return std::numeric_limits::quiet_NaN();
+ #endif
+ }
+ Object::operator long long() const noexcept
+ {
+ #ifdef __NERD_ENV_ARDUINO
+ return 0;
+ #else
+ return std::numeric_limits::quiet_NaN();
+ #endif
+ }
+ Object::operator std::string() const noexcept
+ {
+ return "[object Object]";
+ }
+ // Main operators
+ NerdCore::VAR const Object::operator[](NerdCore::VAR key) const
+ {
+ return NerdCore::Global::null;
+ }
+
+ NerdCore::VAR &Object::GetSet(std::string key)
+ {
+ #ifndef __NERD__OBJECT_VECTOR
+ // if current object[key] is null, we look for the prototypal chain
+ if(object[key].type == NerdCore::Enum::Type::Null)
+ {
+ NerdCore::VAR __proto = object["__proto__"];
+ while(__proto.type != NerdCore::Enum::Type::Null)
+ {
+ if(__proto[key].type != NerdCore::Enum::Type::Null)
+ {
+ object[key] = __proto[key];
+ break;
+ }
+ __proto = __proto["__proto__"];
+ }
+ }
+ /*
+ if(object[key].type == NerdCore::Enum::Type::Function)
+ {
+ (__NERD_FUNCTION(object[key]))->object["this"] = NerdCore::VAR(this);
+ __NERD_FUNCTION(object[key])->bind = bind;
+ }
+ */
+ return object[key];
+ #else
+ for (auto & search : object)
+ {
+ if (key.compare(search.first) == 0)
+ {
+ return search.second;
+ }
+ }
+
+ object.push_back(NerdCore::Type::pair_t(key, NerdCore::Global::null));
+
+ return object[object.size() - 1].second;
+ #endif
+ }
+
+ NerdCore::VAR &Object::operator[](NerdCore::VAR key)
+ {
+ return Object::GetSet(key);
+
+ }
+
+ NerdCore::VAR &Object::operator[](int key)
+ {
+ std::string _str = std::to_string(key);
+ return Object::GetSet(_str);
+ }
+
+ NerdCore::VAR &Object::operator[](double key)
+ {
+ std::string _str = std::to_string(key);
+ return Object::GetSet(_str);
+ }
+
+ NerdCore::VAR &Object::operator[](const char* key)
+ {
+ return Object::GetSet(key);
+ }
+
+ // Comparation operators
+ Object Object::operator!() const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Object();
+ }
+ bool Object::operator==(const Object &_v1) const { return false; }
+ // === emulated with __NERD_EQUAL_VALUE_AND_TYPE
+ // !== emulated with __NERD_NOT_EQUAL_VALUE_AND_TYPE
+ bool Object::operator!=(const Object &_v1) const { return true; }
+ bool Object::operator<(const Object &_v1) const { return false; }
+ bool Object::operator<=(const Object &_v1) const { return true; }
+ bool Object::operator>(const Object &_v1) const { return false; }
+ bool Object::operator>=(const Object &_v1) const { return true; }
+ // Numeric operators
+ Object Object::operator+() const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Object();
+ }
+ Object Object::operator-() const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Object();
+ }
+ Object Object::operator++(const int _v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Object();
+ }
+ Object Object::operator--(const int _v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Object();
+ }
+ Object Object::operator+(const Object &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Object();
+ }
+ Object Object::operator+=(const Object &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Object();
+ }
+ Object Object::operator-(const Object &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Object();
+ }
+ Object Object::operator-=(const Object &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Object();
+ }
+ Object Object::operator*(const Object &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Object();
+ }
+ Object Object::operator*=(const Object &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Object();
+ }
+ // TODO: "**" and "**=" operators
+ Object Object::operator/(const Object &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Object();
+ }
+ Object Object::operator/=(const Object &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Object();
+ }
+ Object Object::operator%(const Object &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Object();
+ }
+ Object Object::operator%=(const Object &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Object();
+ }
+ Object Object::operator&(const Object &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Object();
+ }
+ Object Object::operator|(const Object &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Object();
+ }
+ Object Object::operator^(const Object &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Object();
+ }
+ Object Object::operator~() const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Object();
+ }
+ Object Object::operator>>(const Object &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Object();
+ }
+ Object Object::operator<<(const Object &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Object();
+ }
+ Object Object::operator&=(const Object &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Object();
+ }
+ Object Object::operator|=(const Object &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Object();
+ }
+ Object Object::operator^=(const Object &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Object();
+ }
+ Object Object::operator>>=(const Object &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Object();
+ }
+ Object Object::operator<<=(const Object &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return Object();
+ }
+ // TODO: ">>>" and ">>>=" operators
+} // namespace NerdCore::Class
diff --git a/compiler/native/nerdcore/src/class/object_header.h b/compiler/native/nerdcore/src/class/object_header.h
new file mode 100644
index 000000000..12dc2d9c3
--- /dev/null
+++ b/compiler/native/nerdcore/src/class/object_header.h
@@ -0,0 +1,103 @@
+/*
+ Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
+
+ 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.
+
+*/
+
+#pragma once
+#include "_meta.h"
+
+namespace NerdCore::Class
+{
+ class Object : public virtual Base
+ {
+ public:
+ // Constructors
+ Object();
+ Object(NerdCore::Type::object_t obj);
+ Object(std::initializer_list);
+ //Object(NerdCore::VAR _obj);
+ // Properties
+ count_t counter = 0;
+ bool deleted = false;
+ //bool hasLazy = false;
+ NerdCore::Type::object_t object;
+ void* bind = nullptr;
+ // Methods
+ double Size();
+ inline void Delete() noexcept;
+ inline void jsDelete(const std::string _key) noexcept;
+ inline void* Copy() noexcept;
+ // Native cast
+ explicit operator bool() const noexcept;
+ explicit operator double() const noexcept;
+ explicit operator int() const noexcept;
+ explicit operator long long() const noexcept;
+ explicit operator std::string() const noexcept;
+ // Main operators
+ inline NerdCore::VAR& GetSet(std::string key);
+
+ NerdCore::VAR const operator[](NerdCore::VAR key) const;
+ NerdCore::VAR &operator[](NerdCore::VAR key);
+ NerdCore::VAR &operator[](int key);
+ NerdCore::VAR &operator[](double key);
+ NerdCore::VAR &operator[](const char* key);
+
+
+ // Comparation operators
+ Object operator!() const;
+ bool operator==(const Object &_v1) const;
+ // === emulated with __NERD_EQUAL_VALUE_AND_TYPE
+ // !== emulated with __NERD_NOT_EQUAL_VALUE_AND_TYPE
+ bool operator!=(const Object &_v1) const;
+ bool operator<(const Object &_v1) const;
+ bool operator<=(const Object &_v1) const;
+ bool operator>(const Object &_v1) const;
+ bool operator>=(const Object &_v1) const;
+ // Numeric operators
+ Object operator+() const;
+ Object operator-() const;
+ Object operator++(const int _v1);
+ Object operator--(const int _v1);
+ Object operator+(const Object &_v1) const;
+ Object operator+=(const Object &_v1);
+ Object operator-(const Object &_v1) const;
+ Object operator-=(const Object &_v1);
+ Object operator*(const Object &_v1) const;
+ Object operator*=(const Object &_v1);
+ // TODO: "**" and "**=" operators
+ Object operator/(const Object &_v1) const;
+ Object operator/=(const Object &_v1);
+ Object operator%(const Object &_v1) const;
+ Object operator%=(const Object &_v1);
+ Object operator&(const Object &_v1) const;
+ Object operator|(const Object &_v1) const;
+ Object operator^(const Object &_v1) const;
+ Object operator~() const;
+ Object operator>>(const Object &_v1) const;
+ Object operator<<(const Object &_v1) const;
+ Object operator&=(const Object &_v1);
+ Object operator|=(const Object &_v1);
+ Object operator^=(const Object &_v1);
+ Object operator>>=(const Object &_v1);
+ Object operator<<=(const Object &_v1);
+ // TODO: ">>>" and ">>>=" operators
+ };
+} // namespace NerdCore::Class
diff --git a/compiler/native/nerdcore/src/class/string.h b/compiler/native/nerdcore/src/class/string.h
new file mode 100644
index 000000000..ebebb1205
--- /dev/null
+++ b/compiler/native/nerdcore/src/class/string.h
@@ -0,0 +1,571 @@
+/*
+ Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
+
+ 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.
+
+*/
+
+#pragma once
+#include "string_header.h"
+#include
+#include
+
+namespace NerdCore::Class
+{
+
+ // Constructors
+ String::String()
+ {
+ object["__proto__"] = NerdCore::Global::String["prototype"];
+ }
+ String::String(std::string val)
+ {
+ object["__proto__"] = NerdCore::Global::String["prototype"];
+ value = val;
+ }
+
+ String::String(const char* val)
+ {
+ object["__proto__"] = NerdCore::Global::String["prototype"];
+ value = val;
+ }
+
+ // Methods
+ inline void String::Delete() noexcept
+ {
+ if (--counter < 1)
+ {
+ delete this;
+ }
+ }
+ inline void* String::Copy() noexcept
+ {
+ return new String(value);
+ }
+ // Native cast
+ String::operator bool() const noexcept { return value.size() > 0; }
+ String::operator double() const noexcept
+ {
+ std::string::size_type end;
+ double res;
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ try
+ {
+ res = std::stod(value, &end);
+ }catch(...){}
+ #else
+ res = std::stod(value, &end);
+ #endif
+
+ #ifdef __NERD_ENV_ARDUINO
+ return 0;
+ #else
+ return end == value.size() ? res : std::numeric_limits::quiet_NaN();
+ #endif
+ }
+ String::operator int() const noexcept
+ {
+ std::string::size_type end;
+ int res;
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ try
+ {
+ res = std::stoi(value, &end, 10);
+ }catch(...){}
+ #else
+ res = std::stoi(value, &end, 10);
+ #endif
+
+ #ifdef __NERD_ENV_ARDUINO
+ return 0;
+ #else
+ return end == value.size() ? res : std::numeric_limits::quiet_NaN();
+ #endif
+ }
+ String::operator long long() const noexcept
+ {
+ std::string::size_type end;
+ long long res;
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ try
+ {
+ res = std::stoll(value, &end, 10);
+ }catch(...){}
+ #else
+ res = std::stoll(value, &end, 10);
+ #endif
+
+ #ifdef __NERD_ENV_ARDUINO
+ return 0;
+ #else
+ return end == value.size() ? res : std::numeric_limits::quiet_NaN();
+ #endif
+ }
+ String::operator std::string() const noexcept { return value; }
+ // Main operators
+ NerdCore::VAR const String::operator[](NerdCore::VAR key) const
+ {
+ return NerdCore::Global::null;
+ }
+
+ static NerdCore::Global::var _char = "";
+
+
+
+ NerdCore::VAR &String::GetSet(NerdCore::VAR keyVar)
+ {
+ if(keyVar.type == NerdCore::Enum::Type::Number)
+ {
+ int key = (int)keyVar;
+
+ if(key > value.size() - 1)
+ {
+ return NerdCore::Global::null;
+ }
+ else
+ {
+ _char = std::string(1, value[key]);
+ return _char;
+ }
+ }
+ else if(keyVar.type == NerdCore::Enum::Type::String)
+ {
+ std::string key = ((NerdCore::Class::String*)(keyVar.data.ptr))->value;
+ #ifndef __NERD__OBJECT_VECTOR
+ // if current object[key] is null, we look for the prototypal chain
+ if(object[key].type == NerdCore::Enum::Type::Null)
+ {
+
+ NerdCore::VAR __proto = object["__proto__"];
+ while(__proto.type != NerdCore::Enum::Type::Null)
+ {
+ if(__proto[key].type != NerdCore::Enum::Type::Null)
+ {
+ object[key] = __proto[key];
+ break;
+ }
+ __proto = __proto["__proto__"];
+ }
+ }
+ /*
+ if(object[key].type == NerdCore::Enum::Type::Function)
+ {
+ value.copy((char*)__NERD_FUNCTION(object[key])->bind, value.length());
+ }
+ */
+
+ return object[key];
+ #else
+ for (auto & search : object)
+ {
+ if (key.compare(search.first) == 0)
+ {
+ return search.second;
+ }
+ }
+
+ object.push_back(NerdCore::Type::pair_t(key, NerdCore::Global::null));
+
+ return object[object.size() - 1].second;
+ #endif
+ }
+ else
+ {
+ return NerdCore::Global::null;
+ }
+ }
+
+
+ NerdCore::VAR &String::operator[](NerdCore::VAR key)
+ {
+ return String::GetSet(key);
+ }
+
+ NerdCore::VAR &String::operator[](int key)
+ {
+ return String::GetSet(key);
+ }
+
+ NerdCore::VAR &String::operator[](double key)
+ {
+ return String::GetSet(key);
+ }
+
+ NerdCore::VAR &String::operator[](const char* key)
+ {
+ #ifndef __NERD__OBJECT_VECTOR
+ // if current object[key] is null, we look for the prototypal chain
+ if(object[key].type == NerdCore::Enum::Type::Null)
+ {
+ NerdCore::VAR __proto = object["__proto__"];
+ while(__proto.type != NerdCore::Enum::Type::Null)
+ {
+ if(__proto[key].type != NerdCore::Enum::Type::Null)
+ {
+ object[key] = __proto[key];
+ break;
+ }
+ __proto = __proto["__proto__"];
+ }
+ }
+ /*
+ if(object[key].type == NerdCore::Enum::Type::Function)
+ {
+ //__NERD_FUNCTION(object[key])->bind = value.data();
+ //value.copy((char*)__NERD_FUNCTION(object[key])->bind, value.length());
+ }
+ */
+ return object[key];
+ #else
+ for (auto & search : object)
+ {
+ if (key.compare(search.first) == 0)
+ {
+ return search.second;
+ }
+ }
+
+ object.push_back(NerdCore::Type::pair_t(key, NerdCore::Global::null));
+
+ return object[object.size() - 1].second;
+ #endif
+ }
+
+ // Comparation operators
+ String String::operator!() const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return String();
+ }
+ bool String::operator==(const String &_v1) const { return value.compare(_v1.value) == 0; }
+ // === emulated with __NERD_EQUAL_VALUE_AND_TYPE
+ // !== emulated with __NERD_NOT_EQUAL_VALUE_AND_TYPE
+ bool String::operator!=(const String &_v1) const { return value.compare(_v1.value) != 0; }
+ bool String::operator<(const String &_v1) const { return value.at(0) < _v1.value.at(0); }
+ bool String::operator<=(const String &_v1) const { return value.at(0) <= _v1.value.at(0); }
+ bool String::operator>(const String &_v1) const { return value.at(0) > _v1.value.at(0); }
+ bool String::operator>=(const String &_v1) const { return value.at(0) >= _v1.value.at(0); }
+ // Numeric operators
+ String String::operator+() const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return String();
+ }
+ String String::operator-() const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return String();
+ }
+ String String::operator++(const int _v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return String();
+ }
+ String String::operator--(const int _v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return String();
+ }
+ String String::operator+(const String &_v1) const { return value + _v1.value; }
+ String String::operator+=(const String &_v1) { value += _v1.value; return *this; }
+ String String::operator-(const String &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return String();
+ }
+ String String::operator-=(const String &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return String();
+ }
+ String String::operator*(const String &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return String();
+ }
+ String String::operator*=(const String &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return String();
+ }
+ // TODO: "**" and "**=" operators
+ String String::operator/(const String &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return String();
+ }
+ String String::operator/=(const String &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return String();
+ }
+ String String::operator%(const String &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return String();
+ }
+ String String::operator%=(const String &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return String();
+ }
+ String String::operator&(const String &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return String();
+ }
+ String String::operator|(const String &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return String();
+ }
+ String String::operator^(const String &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return String();
+ }
+ String String::operator~() const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return String();
+ }
+ String String::operator>>(const String &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return String();
+ }
+ String String::operator<<(const String &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return String();
+ }
+ String String::operator&=(const String &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return String();
+ }
+ String String::operator|=(const String &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return String();
+ }
+ String String::operator^=(const String &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return String();
+ }
+ String String::operator>>=(const String &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return String();
+ }
+ String String::operator<<=(const String &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return String();
+ }
+ // TODO: ">>>" and ">>>=" operators
+ /*** STRING METHODS ***/
+ NerdCore::VAR String::toString(NerdCore::VAR* _args, int _length) const
+ {
+ return value;
+ }
+
+ NerdCore::VAR String::split(NerdCore::VAR* _args, int _length) const
+ {
+ NerdCore::VAR _needle;
+ if (_length > 0)
+ _needle = _args[0];
+ else
+ return NerdCore::VAR(this->value);
+
+ NerdCore::VAR _arr = new NerdCore::Class::Array();
+ char *_v = (char *)malloc(strlen(this->value.c_str()) + 1);
+ strcpy(_v, this->value.c_str());
+ char *delim = (char *)malloc(strlen(((std::string)_needle).c_str()) + 1);
+ strcpy(delim, ((std::string)_needle).c_str());
+
+ char *ptr = strtok(_v, delim);
+ int i = 0;
+ char *_new;
+ while (ptr != NULL)
+ {
+ _new = (char *)malloc(strlen(ptr) + 1);
+ strcpy(_new, ptr);
+ __NERD_Object_Set(i, _new, _arr);
+ free(_new);
+ ptr = strtok(NULL, delim);
+ i++;
+ }
+
+ free(delim);
+ return _arr;
+ }
+
+ NerdCore::VAR String::indexOf(NerdCore::VAR* _args, int _length) const
+ {
+ NerdCore::VAR _needle;
+ if (_length > 0)
+ _needle = _args[0];
+ else
+ return NerdCore::VAR(-1);
+
+ std::string::size_type loc = this->value.find((std::string)_needle, 0);
+ if (loc != std::string::npos)
+ {
+ return NerdCore::VAR((int)loc);
+ }
+ return NerdCore::VAR(-1);
+ }
+
+ NerdCore::VAR String::lastIndexOf(NerdCore::VAR* _args, int _length) const
+ {
+ NerdCore::VAR _needle;
+ if (_length > 0)
+ _needle = _args[0];
+ else
+ return NerdCore::VAR(-1);
+
+ std::string::size_type loc = this->value.find_last_of((std::string)_needle, 0);
+ if (loc != std::string::npos)
+ {
+ return NerdCore::VAR((int)loc);
+ }
+ return NerdCore::VAR(-1);
+ }
+
+ NerdCore::VAR String::search(NerdCore::VAR* _args, int _length) const
+ {
+ NerdCore::VAR _needle;
+ if (_length > 0)
+ _needle = _args[0];
+ else
+ return NerdCore::VAR(-1);
+
+ std::string::size_type loc = this->value.find((std::string)_needle, 0);
+ if (loc != std::string::npos)
+ {
+ return NerdCore::VAR((int)loc);
+ }
+ return NerdCore::VAR(-1);
+ }
+
+ NerdCore::VAR String::slice(NerdCore::VAR* _args, int _length) const
+ {
+ NerdCore::VAR _start;
+ NerdCore::VAR _end;
+ if (_length > 0)
+ _start = _args[0];
+ else
+ return NerdCore::VAR(this->value);
+ if (_length > 1)
+ _end = _args[1];
+
+ if (_end.type == NerdCore::Enum::Type::Null)
+ return NerdCore::VAR(this->value.substr((int)_start, std::string::npos));
+ int _endIndex = (int)_end - (int)_start;
+ return NerdCore::VAR(this->value.substr((int)_start, _endIndex));
+ }
+
+ NerdCore::VAR String::substr(NerdCore::VAR* _args, int _length) const
+ {
+ NerdCore::VAR _start;
+ NerdCore::VAR _end;
+ if (_length > 0)
+ _start = _args[0];
+ else
+ return NerdCore::VAR(this->value);
+ if (_length > 1)
+ _end = _args[1];
+
+ if (_end.type == NerdCore::Enum::Type::Null)
+ return NerdCore::VAR(this->value.substr((int)_start, std::string::npos));
+ return NerdCore::VAR(this->value.substr((int)_start, (int)_end));
+ }
+
+ NerdCore::VAR String::replace(NerdCore::VAR* _args, int _length) const
+ {
+ NerdCore::VAR _search;
+ NerdCore::VAR _replace;
+ if (_length > 0)
+ _search = _args[0];
+ else
+ return NerdCore::VAR(this->value);
+ if (_length > 1)
+ _replace = _args[1];
+
+ size_t start_pos = this->value.find((std::string)_search);
+ if (start_pos == std::string::npos)
+ {
+ return NerdCore::VAR(value);
+ }
+
+ std::string _new = value;
+ return NerdCore::VAR(_new.replace(start_pos, ((std::string)_search).length(), (std::string)_replace));
+ }
+ /* END STRING METHODS */
+} // namespace NerdCore::Class
\ No newline at end of file
diff --git a/compiler/native/nerdcore/src/class/string_header.h b/compiler/native/nerdcore/src/class/string_header.h
new file mode 100644
index 000000000..4b6619908
--- /dev/null
+++ b/compiler/native/nerdcore/src/class/string_header.h
@@ -0,0 +1,116 @@
+/*
+ Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
+
+ 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.
+
+*/
+
+#pragma once
+#include "_meta.h"
+
+namespace NerdCore::Class
+{
+ class String : public virtual Base
+ {
+ public:
+ // Constructors
+ String();
+ String(std::string val);
+ String(const char* val);
+ // Properties
+ std::string value;
+ NerdCore::Type::object_t object;
+ NerdCore::VAR length;
+ void* bind = nullptr;
+ count_t counter = 1;
+ // Methods
+ inline void Delete() noexcept;
+ inline void* Copy() noexcept;
+ // Native cast
+ explicit operator bool() const noexcept;
+ explicit operator double() const noexcept;
+ explicit operator int() const noexcept;
+ explicit operator long long() const noexcept;
+ explicit operator std::string() const noexcept;
+ // Main operators
+ inline NerdCore::VAR& GetSet(NerdCore::VAR keyVar);
+ NerdCore::VAR const operator[](NerdCore::VAR key) const;
+ NerdCore::VAR &operator[](NerdCore::VAR key);
+ NerdCore::VAR &operator[](int key);
+ NerdCore::VAR &operator[](double key);
+ NerdCore::VAR &operator[](const char* key);
+
+ // Comparation operators
+ template
+ NerdCore::VAR operator() (Args... args)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NerdCore::Global::null;
+ }
+ String operator!() const;
+ bool operator==(const String &_v1) const;
+ // === emulated with __NERD_EQUAL_VALUE_AND_TYPE
+ // !== emulated with __NERD_NOT_EQUAL_VALUE_AND_TYPE
+ bool operator!=(const String &_v1) const;
+ bool operator<(const String &_v1) const;
+ bool operator<=(const String &_v1) const;
+ bool operator>(const String &_v1) const;
+ bool operator>=(const String &_v1) const;
+ // Numeric operators
+ String operator+() const;
+ String operator-() const;
+ String operator++(const int _v1);
+ String operator--(const int _v1);
+ String operator+(const String &_v1) const;
+ String operator+=(const String &_v1);
+ String operator-(const String &_v1) const;
+ String operator-=(const String &_v1);
+ String operator*(const String &_v1) const;
+ String operator*=(const String &_v1);
+ // TODO: "**" and "**=" operators
+ String operator/(const String &_v1) const;
+ String operator/=(const String &_v1);
+ String operator%(const String &_v1) const;
+ String operator%=(const String &_v1);
+ String operator&(const String &_v1) const;
+ String operator|(const String &_v1) const;
+ String operator^(const String &_v1) const;
+ String operator~() const;
+ String operator>>(const String &_v1) const;
+ String operator<<(const String &_v1) const;
+ String operator&=(const String &_v1);
+ String operator|=(const String &_v1);
+ String operator^=(const String &_v1);
+ String operator>>=(const String &_v1);
+ String operator<<=(const String &_v1);
+ // TODO: ">>>" and ">>>=" operators
+ /*** STRING METHODS ***/
+ NerdCore::VAR toString(NerdCore::VAR* _args, int _length) const;
+ NerdCore::VAR split(NerdCore::VAR* _args, int _length) const;
+ NerdCore::VAR indexOf(NerdCore::VAR* _args, int _length) const;
+ NerdCore::VAR lastIndexOf(NerdCore::VAR* _args, int _length) const;
+ NerdCore::VAR search(NerdCore::VAR* _args, int _length) const;
+ NerdCore::VAR slice(NerdCore::VAR* _args, int _length) const;
+ NerdCore::VAR substr(NerdCore::VAR* _args, int _length) const;
+ NerdCore::VAR replace(NerdCore::VAR* _args, int _length) const;
+ /* END STRING METHODS */
+ };
+} // namespace NerdCore::Class
diff --git a/compiler/native/nerdcore/src/class/struct.h b/compiler/native/nerdcore/src/class/struct.h
new file mode 100644
index 000000000..5b6aff5f5
--- /dev/null
+++ b/compiler/native/nerdcore/src/class/struct.h
@@ -0,0 +1,363 @@
+/*
+ Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
+
+ 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.
+
+*/
+
+#pragma once
+#include "struct_header.h"
+#include
+#include
+
+namespace NerdCore::Class
+{
+ // Constructors
+ Struct::Struct() {}
+ Struct::Struct(void *val)
+ {
+ value = val;
+ }
+ Struct::Struct(void *val, void* fn)
+ {
+ value = val;
+ Clean = (NerdCore::Type::clean_struct*)fn;
+ }
+ // Methods
+ inline void Struct::Delete() noexcept
+ {
+ if (--counter == 0)
+ {
+ (*static_cast(Clean))(value);
+ delete Clean;
+ delete this;
+ }
+ }
+
+ inline void* Struct::Copy() noexcept
+ {
+ counter++;
+ return this;
+ }
+ // Native cast
+ Struct::operator bool() const noexcept { return true; }
+ Struct::operator double() const noexcept
+ {
+ #ifdef __NERD_ENV_ARDUINO
+ return 0;
+ #else
+ return std::numeric_limits::quiet_NaN();
+ #endif
+ }
+ Struct::operator int() const noexcept
+ {
+ #ifdef __NERD_ENV_ARDUINO
+ return 0;
+ #else
+ return std::numeric_limits::quiet_NaN();
+ #endif
+ }
+ Struct::operator long long() const noexcept
+ {
+ #ifdef __NERD_ENV_ARDUINO
+ return 0;
+ #else
+ return std::numeric_limits::quiet_NaN();
+ #endif
+ }
+ Struct::operator std::string() const noexcept
+ {
+ return "[native struct]";
+ }
+ // Main operators
+ NerdCore::VAR const Struct::operator[](NerdCore::VAR key) const
+ {
+ return NerdCore::Global::null;
+ }
+ NerdCore::VAR &Struct::operator[](NerdCore::VAR key)
+ {
+ #ifndef __NERD__OBJECT_VECTOR
+ return object[(std::string)key];
+ #else
+ for (auto & search : object)
+ {
+ if (((std::string)key).compare(search.first) == 0)
+ {
+ return search.second;
+ }
+ }
+
+ object.push_back(NerdCore::Type::pair_t((std::string)key, NerdCore::VAR()));
+ return object[object.size() - 1].second;
+ #endif
+ }
+
+ NerdCore::VAR &Struct::operator[](int key)
+ {
+ #ifndef __NERD__OBJECT_VECTOR
+ return object[std::to_string(key)];
+ #else
+ std::string _str = std::to_string(key);
+ for (auto & search : object)
+ {
+ if (_str.compare(search.first) == 0)
+ {
+ return search.second;
+ }
+ }
+
+ object.push_back(NerdCore::Type::pair_t(_str, NerdCore::VAR()));
+ return object[object.size() - 1].second;
+ #endif
+ }
+
+ NerdCore::VAR &Struct::operator[](double key)
+ {
+ #ifndef __NERD__OBJECT_VECTOR
+ return object[std::to_string(key)];
+ #else
+ std::string _str = std::to_string(key);
+ for (auto & search : object)
+ {
+ if (_str.compare(search.first) == 0)
+ {
+ return search.second;
+ }
+ }
+
+ object.push_back(NerdCore::Type::pair_t(_str, NerdCore::VAR()));
+ return object[object.size() - 1].second;
+ #endif
+ }
+
+
+ NerdCore::VAR &Struct::operator[](const char* key)
+ {
+ std::string str = key;
+ #ifndef __NERD__OBJECT_VECTOR
+ return object[str];
+ #else
+ for (auto & search : object)
+ {
+ if (str.compare(search.first) == 0)
+ {
+ return search.second;
+ }
+ }
+
+ object.push_back(NerdCore::Type::pair_t(str, NerdCore::VAR()));
+ return object[object.size() - 1].second;
+ #endif
+ }
+
+ // Comparation operators
+ NerdCore::VAR Struct::operator!() const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NerdCore::VAR();
+ }
+ bool Struct::operator==(const NerdCore::VAR &_v1) const { return false; }
+ // === emulated with __NERD_EQUAL_VALUE_AND_TYPE
+ // !== emulated with __NERD_NOT_EQUAL_VALUE_AND_TYPE
+ bool Struct::operator!=(const NerdCore::VAR &_v1) const { return true; }
+ bool Struct::operator<(const NerdCore::VAR &_v1) const { return false; }
+ bool Struct::operator<=(const NerdCore::VAR &_v1) const { return true; }
+ bool Struct::operator>(const NerdCore::VAR &_v1) const { return false; }
+ bool Struct::operator>=(const NerdCore::VAR &_v1) const { return true; }
+ // Numeric operators
+ NerdCore::VAR Struct::operator+() const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NerdCore::VAR();
+ }
+ NerdCore::VAR Struct::operator-() const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NerdCore::VAR();
+ }
+ NerdCore::VAR Struct::operator++(const int _v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NerdCore::VAR();
+ }
+ NerdCore::VAR Struct::operator--(const int _v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NerdCore::VAR();
+ }
+ NerdCore::VAR Struct::operator+(const NerdCore::VAR &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NerdCore::VAR();
+ }
+ NerdCore::VAR Struct::operator+=(const NerdCore::VAR &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NerdCore::VAR();
+ }
+ NerdCore::VAR Struct::operator-(const NerdCore::VAR &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NerdCore::VAR();
+ }
+ NerdCore::VAR Struct::operator-=(const NerdCore::VAR &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NerdCore::VAR();
+ }
+ NerdCore::VAR Struct::operator*(const NerdCore::VAR &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NerdCore::VAR();
+ }
+ NerdCore::VAR Struct::operator*=(const NerdCore::VAR &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NerdCore::VAR();
+ }
+ // TODO: "**" and "**=" operators
+ NerdCore::VAR Struct::operator/(const NerdCore::VAR &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NerdCore::VAR();
+ }
+ NerdCore::VAR Struct::operator/=(const NerdCore::VAR &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NerdCore::VAR();
+ }
+ NerdCore::VAR Struct::operator%(const NerdCore::VAR &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NerdCore::VAR();
+ }
+ NerdCore::VAR Struct::operator%=(const NerdCore::VAR &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NerdCore::VAR();
+ }
+ NerdCore::VAR Struct::operator&(const NerdCore::VAR &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NerdCore::VAR();
+ }
+ NerdCore::VAR Struct::operator|(const NerdCore::VAR &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NerdCore::VAR();
+ }
+ NerdCore::VAR Struct::operator^(const NerdCore::VAR &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NerdCore::VAR();
+ }
+ NerdCore::VAR Struct::operator~() const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NerdCore::VAR();
+ }
+ NerdCore::VAR Struct::operator>>(const NerdCore::VAR &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NerdCore::VAR();
+ }
+ NerdCore::VAR Struct::operator<<(const NerdCore::VAR &_v1) const
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NerdCore::VAR();
+ }
+ NerdCore::VAR Struct::operator&=(const NerdCore::VAR &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NerdCore::VAR();
+ }
+ NerdCore::VAR Struct::operator|=(const NerdCore::VAR &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NerdCore::VAR();
+ }
+ NerdCore::VAR Struct::operator^=(const NerdCore::VAR &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NerdCore::VAR();
+ }
+ NerdCore::VAR Struct::operator>>=(const NerdCore::VAR &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NerdCore::VAR();
+ }
+ NerdCore::VAR Struct::operator<<=(const NerdCore::VAR &_v1)
+ {
+ #if !defined(__NERD_ENV_ARDUINO) && !defined(__NERD_ENV_ESP32)
+ throw InvalidTypeException();
+ #endif
+ return NerdCore::VAR();
+ }
+ // TODO: ">>>" and ">>>=" operators
+} // namespace NerdCore::Class
diff --git a/compiler/native/nerdcore/src/class/struct_header.h b/compiler/native/nerdcore/src/class/struct_header.h
new file mode 100644
index 000000000..bd1251f3d
--- /dev/null
+++ b/compiler/native/nerdcore/src/class/struct_header.h
@@ -0,0 +1,104 @@
+/*
+ Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
+
+ 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.
+
+*/
+
+#pragma once
+#include "_meta.h"
+
+namespace NerdCore::Class
+{
+ class Struct : public virtual Base
+ {
+ public:
+ // Constructors
+ Struct();
+ Struct(void* val);
+ Struct(void* val, void* fn);
+ // Properties
+ count_t counter = 1;
+ void* value = nullptr;
+ NerdCore::Type::object_t object;
+ NerdCore::Type::clean_struct* Clean;
+ // Methods
+ inline void Delete() noexcept;
+ inline void StructDelete() noexcept;
+ inline void* Copy() noexcept;
+ // Struct cast
+ explicit operator bool() const noexcept;
+ explicit operator double() const noexcept;
+ explicit operator int() const noexcept;
+ explicit operator long long() const noexcept;
+ explicit operator std::string() const noexcept;
+ // Main operators
+ NerdCore::VAR const operator[](NerdCore::VAR key) const;
+ NerdCore::VAR &operator[](NerdCore::VAR key);
+ NerdCore::VAR &operator[](int key);
+ NerdCore::VAR &operator[](double key);
+ NerdCore::VAR &operator[](const char* key);
+
+ template
+ NerdCore::VAR operator()(Args... args) const
+ {
+ auto _args = NerdCore::Type::vector_t{(NerdCore::VAR)args...};
+ return (*static_cast *>(value))(_args);
+ }
+
+ // Comparation operators
+ NerdCore::VAR operator!() const;
+ bool operator==(const NerdCore::VAR &_v1) const;
+ // === emulated with __NERD_EQUAL_VALUE_AND_TYPE
+ // !== emulated with __NERD_NOT_EQUAL_VALUE_AND_TYPE
+ bool operator!=(const NerdCore::VAR &_v1) const;
+ bool operator<(const NerdCore::VAR &_v1) const;
+ bool operator<=(const NerdCore::VAR &_v1) const;
+ bool operator>(const NerdCore::VAR &_v1) const;
+ bool operator>=(const NerdCore::VAR &_v1) const;
+ // Numeric operators
+ NerdCore::VAR operator+() const;
+ NerdCore::VAR operator-() const;
+ NerdCore::VAR operator++(const int _v1);
+ NerdCore::VAR operator--(const int _v1);
+ NerdCore::VAR operator+(const NerdCore::VAR &_v1) const;
+ NerdCore::VAR operator+=(const NerdCore::VAR &_v1);
+ NerdCore::VAR operator-(const NerdCore::VAR &_v1) const;
+ NerdCore::VAR operator-=(const NerdCore::VAR &_v1);
+ NerdCore::VAR operator*(const NerdCore::VAR &_v1) const;
+ NerdCore::VAR operator*=(const NerdCore::VAR &_v1);
+ // TODO: "**" and "**=" operators
+ NerdCore::VAR operator/(const NerdCore::VAR &_v1) const;
+ NerdCore::VAR operator/=(const NerdCore::VAR &_v1);
+ NerdCore::VAR operator%(const NerdCore::VAR &_v1) const;
+ NerdCore::VAR operator%=(const NerdCore::VAR &_v1);
+ NerdCore::VAR operator&(const NerdCore::VAR &_v1) const;
+ NerdCore::VAR operator|(const NerdCore::VAR &_v1) const;
+ NerdCore::VAR operator^(const NerdCore::VAR &_v1) const;
+ NerdCore::VAR operator~() const;
+ NerdCore::VAR operator>>(const NerdCore::VAR &_v1) const;
+ NerdCore::VAR operator<<(const NerdCore::VAR &_v1) const;
+ NerdCore::VAR operator&=(const NerdCore::VAR &_v1);
+ NerdCore::VAR operator|=(const NerdCore::VAR &_v1);
+ NerdCore::VAR operator^=(const NerdCore::VAR &_v1);
+ NerdCore::VAR operator>>=(const NerdCore::VAR &_v1);
+ NerdCore::VAR operator<<=(const NerdCore::VAR &_v1);
+ // TODO: ">>>" and ">>>=" operators
+ };
+} // namespace NerdCore::Class
diff --git a/compiler/native/nerdcore/src/classes.h b/compiler/native/nerdcore/src/classes.h
new file mode 100644
index 000000000..2604f65f1
--- /dev/null
+++ b/compiler/native/nerdcore/src/classes.h
@@ -0,0 +1,32 @@
+/*
+ Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
+
+ 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.
+
+*/
+
+#pragma once
+
+#include "./class/array.h"
+#include "./class/function.h"
+#include "./class/native.h"
+#include "./class/struct.h"
+#include "./class/fixed_array.h"
+#include "./class/object.h"
+#include "./class/string.h"
diff --git a/compiler/native/nerdcore/src/classes_header.h b/compiler/native/nerdcore/src/classes_header.h
new file mode 100644
index 000000000..a32216e78
--- /dev/null
+++ b/compiler/native/nerdcore/src/classes_header.h
@@ -0,0 +1,35 @@
+/*
+ Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
+
+ 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.
+
+*/
+
+#pragma once
+#define __INC_Nerd_CLASSES_HEADER
+
+#include "./class/base_header.h"
+#include "./class/array_header.h"
+#include "./class/object_header.h"
+#include "./class/function_header.h"
+#include "./class/native_header.h"
+//#include "./class/native_tpl_header.h"
+#include "./class/struct_header.h"
+#include "./class/fixed_array_header.h"
+#include "./class/string_header.h"
diff --git a/compiler/native/nerdcore/src/enum.h b/compiler/native/nerdcore/src/enum.h
new file mode 100644
index 000000000..52e9b5362
--- /dev/null
+++ b/compiler/native/nerdcore/src/enum.h
@@ -0,0 +1,40 @@
+/*
+ Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
+
+ 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.
+
+*/
+
+namespace NerdCore::Enum
+{
+ enum Type
+ {
+ Null,
+ Boolean,
+ Number,
+ String,
+ Native,
+ NativeTPL,
+ Struct,
+ FixedArray,
+ Array,
+ Object,
+ Function,
+ };
+}
\ No newline at end of file
diff --git a/compiler/native/nerdcore/src/functions.h b/compiler/native/nerdcore/src/functions.h
new file mode 100644
index 000000000..a5c97689b
--- /dev/null
+++ b/compiler/native/nerdcore/src/functions.h
@@ -0,0 +1,32 @@
+/*
+ Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
+
+ 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.
+
+*/
+
+NerdCore::VAR getArguments(int argc, char** argv)
+{
+ NerdCore::VAR __NJS_ARGS = new NerdCore::Class::Array();
+ for( int i = 0; i < argc; i++)
+ {
+ __NJS_ARGS[i] = argv[i];
+ }
+ return __NJS_ARGS;
+}
diff --git a/compiler/native/nerdcore/src/functions_header.h b/compiler/native/nerdcore/src/functions_header.h
new file mode 100644
index 000000000..6d4b63c99
--- /dev/null
+++ b/compiler/native/nerdcore/src/functions_header.h
@@ -0,0 +1,111 @@
+/*
+ Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
+
+ 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.
+
+*/
+
+NerdCore::VAR __NERD_Log_Console(NerdCore::VAR _var);
+NerdCore::VAR __NERD_Object_Keys(NerdCore::VAR _var);
+NerdCore::VAR __NERD_Object_Stringify(NerdCore::VAR _var);
+NerdCore::VAR __NERD_Object_Stringify(NerdCore::VAR _var, bool _bracket);
+NerdCore::VAR __NERD_Object_Clone(NerdCore::VAR& _var);
+NerdCore::VAR __NERD_Object_Set(std::string _index, NerdCore::VAR _value, NerdCore::Type::object_t *_obj);
+std::string __NERD_DOUBLE_TO_STRING(double _var);
+
+/*** String MANIPULATION ***/
+
+#ifdef __NERD_ENV_ARDUINO
+namespace std
+{
+ template
+ string to_string(m _var)
+ {
+ std::stringstream output;
+ output << _var;
+ return output.str();
+ }
+ int isnan(double __x)
+ {
+ return ::isnan(__x);
+ }
+ inline int isfinite(double __x)
+ {
+ return ::isfinite(__x);
+ }
+ inline int signbit(double __x)
+ {
+ return ::signbit(__x);
+ }
+ inline double stod(std::string _str, std::string::size_type* sz)
+ {
+ *sz = _str.length();
+ return String(_str.c_str()).toFloat();
+ }
+ inline int stoi(std::string _str, std::string::size_type* sz, int _base)
+ {
+ *sz = _str.length();
+ return String(_str.c_str()).toInt();
+ }
+ inline long long stoll(std::string _str, std::string::size_type* sz, int _base)
+ {
+ *sz = _str.length();
+ return atol(_str.c_str());
+ }
+}
+
+template
+m remainder(m _dividend, n _divisor)
+{
+ m quotient = (int)_dividend / (int)_divisor;
+ m remainder = (int)_dividend % (int)_divisor;
+ return remainder;
+}
+#endif
+template
+std::string __NERD_Concat_To_Str(m _left, n _right)
+{
+ std::stringstream output;
+ output << _left << _right;
+ return output.str();
+}
+/* END String MANIPULATION */
+
+/*** Number MANIPULATION ***/
+template
+int __NERD_Str_To_Int(m _left)
+{
+ int out;
+ std::stringstream output;
+ output << _left;
+ output >> out;
+ return out;
+}
+template
+double __NERD_Str_To_Double(m _left)
+{
+ double out;
+ std::stringstream output;
+ output << _left;
+ output >> out;
+ return out;
+}
+/* END Number MANIPULATION */
+
+NerdCore::VAR getArguments(int argc, char** argv);
\ No newline at end of file
diff --git a/compiler/native/nerdcore/src/macro.h b/compiler/native/nerdcore/src/macro.h
new file mode 100644
index 000000000..140b59937
--- /dev/null
+++ b/compiler/native/nerdcore/src/macro.h
@@ -0,0 +1,67 @@
+/*
+ Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
+
+ 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.
+
+*/
+
+/*** HELPERS ***/
+#define __NERD_GET_String(_var) _var.get().s->value
+#define __NERD_Create_Boolean(_value) NerdCore::VAR(NerdCore::Enum::Type::Boolean, _value)
+#define __NERD_Create_Number(_value) NerdCore::VAR(_value)
+#define __NERD_Create_Function(_value) NerdCore::VAR(NerdCore::Enum::Type::Function, _value)
+#define __NERD_Create_Undefined() NerdCore::VAR()
+#define __NERD_Create_String(_value) NerdCore::VAR(_value)
+#define __NERD_Create_Infinity() NerdCore::VAR(std::numeric_limits::infinity)
+#define __NERD_Create_Null() NerdCore::VAR(NerdCore::Enum::Type::Null, 0)
+#define __NERD_Create_Struct(_value) NerdCore::VAR(new _value(), new NerdCore::Type::clean_struct([](void* _ptr){ delete (_value*)_ptr;}))
+#define __NERD_Create_FixedArray(_length) NerdCore::VAR(new NerdCore::Class::FixedArray(_length))
+#define __NERD_Create_Lambda(name) NerdCore::Type::function_t* name = new NerdCore::Type::function_t([](NerdCore::VAR& __NERD_THIS, NerdCore::VAR* __NERD_VARARGS, int __NERD_VARLENGTH)
+
+#define __NERD_Create_Ptr_Scoped_Anon(__CONTENT__) new NerdCore::Type::function_t([&](NerdCore::VAR& __NERD_THIS, NerdCore::VAR* __NERD_VARARGS, int __NERD_VARLENGTH) mutable -> NerdCore::Global::var { __CONTENT__ })
+#define __NERD_Create_Ptr_Scoped_Copy_Anon(__CONTENT__) new NerdCore::Type::function_t([=](NerdCore::VAR& __NERD_THIS, NerdCore::VAR* __NERD_VARARGS, int __NERD_VARLENGTH) mutable -> NerdCore::Global::var { __CONTENT__ })
+#define __NERD_Create_Ptr_Scoped_Copy_Anon_With_Ref(__FN__, __CONTENT__) new NerdCore::Type::function_t([=, &__FN__](NerdCore::VAR& __NERD_THIS, NerdCore::VAR* __NERD_VARARGS, int __NERD_VARLENGTH) mutable -> NerdCore::Global::var { __CONTENT__ })
+#define __NERD_Create_Ptr_Unscoped_With_Copy(__FN__, __CONTENT__) new NerdCore::Type::function_t([__FN__](NerdCore::VAR& __NERD_THIS, NerdCore::VAR* __NERD_VARARGS, int __NERD_VARLENGTH) mutable -> NerdCore::Global::var { __CONTENT__ })
+#define __NERD_Create_Ptr_Unscoped_Anon(__CONTENT__) new NerdCore::Type::function_t([](NerdCore::VAR& __NERD_THIS, NerdCore::VAR* __NERD_VARARGS, int __NERD_VARLENGTH) -> NerdCore::Global::var{ __CONTENT__ })
+
+#define __NERD_Create_Var_Scoped_Anon(__CONTENT__) NerdCore::VAR(NerdCore::Enum::Type::Function, __NERD_Create_Ptr_Scoped_Anon(__CONTENT__))
+#define __NERD_Create_Var_Unscoped_Anon(__CONTENT__) NerdCore::VAR(NerdCore::Enum::Type::Function, __NERD_Create_Ptr_Unscoped_Anon(__CONTENT__))
+#define __NERD_Create_Var_Scoped_Copy_Anon(__CONTENT__) NerdCore::VAR(NerdCore::Enum::Type::Function, __NERD_Create_Ptr_Scoped_Copy_Anon(__CONTENT__))
+#define __NERD_Create_Var_Unscoped_With_Copy(__FN__, __CONTENT__) NerdCore::VAR(NerdCore::Enum::Type::Function, __NERD_Create_Ptr_Unscoped_With_Copy(__FN__, __CONTENT__))
+#define __NERD_Create_Var_Scoped_Copy_Anon_With_Ref(__FN__, __CONTENT__) NerdCore::VAR(NerdCore::Enum::Type::Function, __NERD_Create_Ptr_Scoped_Copy_Anon_With_Ref(__FN__, __CONTENT__))
+
+#define __NERD_Init_Int(_name, _value) int _name = _value
+#define __NERD_Init_Double(_name, _value) double _name = _value
+#define __NERD_Init_String(_name, _value) std::string _name = _value
+#define __NERD_EXCEPTION_PARAMETER NerdCore::VAR &e
+#define finally ;
+#define __NERD_Throw_Error(_err) NerdCore::VAR(NerdCore::VAR(_err) + NerdCore::VAR(", line: ") + std::to_string(__LINE__) + NerdCore::VAR(", file: ") + NerdCore::VAR(__FILE__))
+#define __NERD_Boolean_TRUE __NERD_Create_Boolean(true)
+#define __NERD_Boolean_FALSE __NERD_Create_Boolean(false)
+#define __NERD_FAST_INT double
+#define __NERD_CreateMethodToClass(_name, _fn) __NERD_Object_Set(_name, __NERD_Create_Var_Scoped_Anon( return _fn(NerdCore::VAR& __NERD_THIS, __NERD_VARARGS, __NERD_VARLENGTH); ), &object);
+#define __NERD_NEW(_fn) ((NerdCore::Class::Function*)_fn.data.ptr)->New
+#define __NERD_Access_Struct(_exp, _name) (*(_name*)((NerdCore::Class::Struct*)_exp.data.ptr)->value)
+#define arguments() new NerdCore::Class::FixedArray(__NERD_VARARGS, __NERD_VARLENGTH);
+//#define __NERD_Native_Ptr(_var, _type) ((_type)((NerdCore::Class::NativeTPL<_type>*)_var.data.ptr)->value)
+#define __NERD_OBJECT(_var) ((NerdCore::Class::Object*)_var.data.ptr)
+#define __NERD_ARRAY(_var) ((NerdCore::Class::Array*)_var.data.ptr)
+#define __NERD_FUNCTION(_var) ((NerdCore::Class::Function*)_var.data.ptr)
+#define __NERD_BIND(_var, _function, _bind) _var = _function;((NerdCore::Class::Function*)_var.data.ptr)->bind = _bind;
+#define Prototype() __NERD_Create_Var_Scoped_Copy_Anon( return __NERD_THIS; )
diff --git a/compiler/native/nerdcore/src/native.h b/compiler/native/nerdcore/src/native.h
new file mode 100644
index 000000000..3ad813a6e
--- /dev/null
+++ b/compiler/native/nerdcore/src/native.h
@@ -0,0 +1,25 @@
+/*
+ Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
+
+ 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.
+
+*/
+
+#include "native/int.h"
+#include "native/double.h"
diff --git a/compiler/native/nerdcore/src/native/double.h b/compiler/native/nerdcore/src/native/double.h
new file mode 100644
index 000000000..a26768f71
--- /dev/null
+++ b/compiler/native/nerdcore/src/native/double.h
@@ -0,0 +1,108 @@
+/*
+ Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
+
+ 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.
+
+*/
+
+NerdCore::VAR operator+(double _i, NerdCore::VAR _v)
+{
+ if(_v.type == NerdCore::Enum::Type::String) return __NERD_DOUBLE_TO_STRING(_i) + (std::string)_v;
+ else return _i + (double)_v;
+}
+
+void operator+=(double& _i, NerdCore::VAR _v)
+{
+ _i += (double)_v;
+}
+
+double operator-(double _i, NerdCore::VAR _v)
+{
+ if(_v.type == NerdCore::Enum::Type::String) return std::numeric_limits::quiet_NaN();
+ return _i - (double)_v;
+}
+
+void operator-=(double& _i, NerdCore::VAR _v)
+{
+ _i -= (double)_v;
+}
+
+double operator*(double _i, NerdCore::VAR _v)
+{
+ if(_v.type == NerdCore::Enum::Type::String) return std::numeric_limits::quiet_NaN();
+ return _i * (double)_v;
+}
+
+void operator*=(double& _i, NerdCore::VAR _v)
+{
+ _i *= (double)_v;
+}
+
+double operator/(double _i, NerdCore::VAR _v)
+{
+ if(_v.type == NerdCore::Enum::Type::String) return std::numeric_limits::quiet_NaN();
+ return _i / (double)_v;
+}
+
+void operator/=(double& _i, NerdCore::VAR _v)
+{
+ _i /= _v;
+}
+
+double operator%(double _i, NerdCore::VAR _v)
+{
+ return (int)_i % (int)_v;
+}
+
+void operator%=(double& _i, NerdCore::VAR _v)
+{
+ _i %= _v;
+}
+
+double operator==(double _i, NerdCore::VAR _v)
+{
+ return _i == (double)_v;
+}
+
+double operator!=(double _i, NerdCore::VAR _v)
+{
+ return _i != (double)_v;
+}
+
+double operator>(double _i, NerdCore::VAR _v)
+{
+ return _i > (double)_v;
+}
+
+double operator>=(double _i, NerdCore::VAR _v)
+{
+ return _i >= (double)_v;
+}
+
+
+double operator<(double _i, NerdCore::VAR _v)
+{
+ return _i < (double)_v;
+}
+
+
+double operator<=(double _i, NerdCore::VAR _v)
+{
+ return _i <= (double)_v;
+}
\ No newline at end of file
diff --git a/compiler/native/nerdcore/src/native/double_header.h b/compiler/native/nerdcore/src/native/double_header.h
new file mode 100644
index 000000000..d0ccadb39
--- /dev/null
+++ b/compiler/native/nerdcore/src/native/double_header.h
@@ -0,0 +1,39 @@
+/*
+ Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
+
+ 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.
+
+*/
+
+NerdCore::VAR operator+(double _i, NerdCore::VAR _v);
+void operator+=(double& _i, NerdCore::VAR _v);
+double operator-(double _i, NerdCore::VAR _v);
+void operator-=(double& _i, NerdCore::VAR _v);
+double operator*(double _i, NerdCore::VAR _v);
+void operator*=(double& _i, NerdCore::VAR _v);
+double operator/(double _i, NerdCore::VAR _v);
+void operator/=(double& _i, NerdCore::VAR _v);
+double operator%(double _i, NerdCore::VAR _v);
+void operator%=(double& _i, NerdCore::VAR _v);
+double operator==(double _i, NerdCore::VAR _v);
+double operator!=(double _i, NerdCore::VAR _v);
+double operator>(double _i, NerdCore::VAR _v);
+double operator>=(double _i, NerdCore::VAR _v);
+double operator<(double _i, NerdCore::VAR _v);
+double operator<=(double _i, NerdCore::VAR _v);
diff --git a/compiler/native/nerdcore/src/native/int.h b/compiler/native/nerdcore/src/native/int.h
new file mode 100644
index 000000000..ca72ba207
--- /dev/null
+++ b/compiler/native/nerdcore/src/native/int.h
@@ -0,0 +1,105 @@
+/*
+ Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
+
+ 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.
+
+*/
+
+NerdCore::VAR operator+(int _i, NerdCore::VAR _v)
+{
+ if(_v.type == NerdCore::Enum::Type::String) return __NERD_DOUBLE_TO_STRING(_i) + (std::string)_v;
+ else return _i + (double)_v;
+}
+
+void operator+=(int& _i, NerdCore::VAR _v)
+{
+ _i += (double)_v;
+}
+
+double operator-(int _i, NerdCore::VAR _v)
+{
+ return _i - (double)_v;
+}
+
+void operator-=(int& _i, NerdCore::VAR _v)
+{
+ _i -= (double)_v;
+}
+
+double operator*(int _i, NerdCore::VAR _v)
+{
+ return _i * (double)_v;
+}
+
+void operator*=(int& _i, NerdCore::VAR _v)
+{
+ _i *= _v;
+}
+
+double operator/(int _i, NerdCore::VAR _v)
+{
+ return _i / (double)_v;
+}
+
+void operator/=(int& _i, NerdCore::VAR _v)
+{
+ _i /= _v;
+}
+
+double operator%(int _i, NerdCore::VAR _v)
+{
+ return (int)_i % (int)_v;
+}
+
+void operator%=(int& _i, NerdCore::VAR _v)
+{
+ _i %= _v;
+}
+
+double operator==(int _i, NerdCore::VAR _v)
+{
+ return _i == (double)_v;
+}
+
+double operator!=(int _i, NerdCore::VAR _v)
+{
+ return _i != (double)_v;
+}
+
+double operator>(int _i, NerdCore::VAR _v)
+{
+ return _i > (double)_v;
+}
+
+double operator>=(int _i, NerdCore::VAR _v)
+{
+ return _i >= (double)_v;
+}
+
+
+double operator<(int _i, NerdCore::VAR _v)
+{
+ return _i < (double)_v;
+}
+
+
+double operator<=(int _i, NerdCore::VAR _v)
+{
+ return _i <= (double)_v;
+}
diff --git a/compiler/native/nerdcore/src/native/int_header.h b/compiler/native/nerdcore/src/native/int_header.h
new file mode 100644
index 000000000..b44be3424
--- /dev/null
+++ b/compiler/native/nerdcore/src/native/int_header.h
@@ -0,0 +1,39 @@
+/*
+ Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
+
+ 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.
+
+*/
+
+NerdCore::VAR operator+(int _i, NerdCore::VAR _v);
+void operator+=(int& _i, NerdCore::VAR _v);
+double operator-(int _i, NerdCore::VAR _v);
+void operator-=(int& _i, NerdCore::VAR _v);
+double operator*(int _i, NerdCore::VAR _v);
+void operator*=(int& _i, NerdCore::VAR _v);
+double operator/(int _i, NerdCore::VAR _v);
+void operator/=(int& _i, NerdCore::VAR _v);
+double operator%(int _i, NerdCore::VAR _v);
+void operator%=(int& _i, NerdCore::VAR _v);
+double operator==(int _i, NerdCore::VAR _v);
+double operator!=(int _i, NerdCore::VAR _v);
+double operator>(int _i, NerdCore::VAR _v);
+double operator>=(int _i, NerdCore::VAR _v);
+double operator<(int _i, NerdCore::VAR _v);
+double operator<=(int _i, NerdCore::VAR _v);
diff --git a/compiler/native/nerdcore/src/native_header.h b/compiler/native/nerdcore/src/native_header.h
new file mode 100644
index 000000000..647e376ab
--- /dev/null
+++ b/compiler/native/nerdcore/src/native_header.h
@@ -0,0 +1,25 @@
+/*
+ Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
+
+ 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.
+
+*/
+
+#include "native/int_header.h"
+#include "native/double_header.h"
diff --git a/compiler/native/nerdcore/src/nerd.cpp b/compiler/native/nerdcore/src/nerd.cpp
new file mode 100644
index 000000000..c08b128ac
--- /dev/null
+++ b/compiler/native/nerdcore/src/nerd.cpp
@@ -0,0 +1,34 @@
+/*
+ Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
+
+ 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.
+
+*/
+
+#include "nerd.hpp"
+
+#include "functions.h"
+#include "native.h"
+#include "values.h"
+#include "class/number.h"
+#include "var.h"
+#include "objmgmt.h"
+#include "classes.h"
+#include "operator.h"
+#include "stdfn.h"
\ No newline at end of file
diff --git a/compiler/native/nerdcore/src/nerd.hpp b/compiler/native/nerdcore/src/nerd.hpp
new file mode 100644
index 000000000..dc20ca359
--- /dev/null
+++ b/compiler/native/nerdcore/src/nerd.hpp
@@ -0,0 +1,96 @@
+/*
+ Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
+
+ 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.
+
+*/
+
+#define _USE_MATH_DEFINES
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#define _USE_MATH_DEFINES
+#include
+#include
+#include
+
+
+#ifdef __NERD_ENV_ARDUINO
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#undef max
+#undef min
+#include
+#else
+#include
+#include
+#include
+#include
+#include
+#include
+#endif
+
+#include "enum.h"
+#include "macro.h"
+
+namespace NerdCore
+{
+ struct VAR;
+
+ namespace Class
+ {
+ class Base;
+ class Undefined;
+ class Boolean;
+ class String;
+ class Array;
+ class Object;
+ class Function;
+ class Native;
+ class Struct;
+ class FixedArray;
+
+
+ //template
+ //class NativeTPL;
+ }
+} // namespace NerdCore
+#include "type_header.h"
+#include "var_header.h"
+#include "values_header.h"
+#include "functions_header.h"
+#include "classes_header.h"
+#include "native_header.h"
+#include "class/number_header.h"
+#include "objmgmt_header.h"
+#include "operator_header.h"
+#include "stdfn_header.h"
diff --git a/compiler/native/nerdcore/src/objmgmt.h b/compiler/native/nerdcore/src/objmgmt.h
new file mode 100644
index 000000000..4c7e4dda2
--- /dev/null
+++ b/compiler/native/nerdcore/src/objmgmt.h
@@ -0,0 +1,127 @@
+/*
+ Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
+
+ 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.
+
+*/
+
+NerdCore::VAR __NERD_delete(NerdCore::VAR _left, NerdCore::VAR _right)
+{
+ if(_left.type == NerdCore::Enum::Type::Object)
+ {
+ ((NerdCore::Class::Object*)_left.data.ptr)->jsDelete(_right);
+ return __NERD_Boolean_TRUE;
+ }
+ else if(_left.type == NerdCore::Enum::Type::Array)
+ {
+ ((NerdCore::Class::Array*)_left.data.ptr)->jsDelete(_right);
+ return __NERD_Boolean_TRUE;
+ }
+ else if(_left.type == NerdCore::Enum::Type::Function)
+ {
+ ((NerdCore::Class::Function*)_left.data.ptr)->jsDelete(_right);
+ return __NERD_Boolean_TRUE;
+ }
+ return __NERD_Boolean_FALSE;
+}
+
+/*** ***/
+#ifndef __NERD__OBJECT_VECTOR
+NerdCore::VAR __NERD_Object_Set(std::string _index, NerdCore::VAR _value, NerdCore::Type::object_t *_obj)
+{
+
+ if (_value.type == NerdCore::Enum::Type::String)
+ {
+ (*_obj)[_index] = new NerdCore::Class::String((std::string)_value);
+ }
+ else
+ {
+ (*_obj)[_index].data.ptr = _value.data.ptr;
+ }
+
+ return NerdCore::Global::null;
+}
+#else
+NerdCore::VAR __NERD_Object_Set(std::string _index, NerdCore::VAR _value, NerdCore::Type::object_t *_obj)
+{
+ int _j = (*_obj).size();
+ for (int _i = 0; _i < _j; _i++)
+ {
+ if (_index.compare((*_obj)[_i].first) == 0)
+ {
+
+ if (_value.type == NerdCore::Enum::Type::String)
+ {
+ (*_obj)[_i].second = new NerdCore::Class::String((std::string)_value);
+ }
+ else
+ {
+ (*_obj)[_i].second.data.ptr = _value.data.ptr;
+ }
+
+ return NerdCore::Global::null;
+ }
+ }
+
+ (*_obj).push_back(NerdCore::Type::pair_t(_index, _value));
+ return NerdCore::Global::null;
+}
+#endif
+/**/
+
+NerdCore::VAR __NERD_Object_Set(NerdCore::VAR _index, NerdCore::VAR _value, NerdCore::VAR _array)
+{
+ if (_array.type == NerdCore::Enum::Type::Array && _index.type == NerdCore::Enum::Type::Number)
+ {
+
+ if (((NerdCore::Class::Array*)_array.data.ptr)->value.size() <= (int)_index.data.number)
+ {
+ ((NerdCore::Class::Array*)_array.data.ptr)->value.resize( (int)_index.data.number + 1);
+ }
+
+ ((NerdCore::Class::Array*)_array.data.ptr)->value.at( (int)_index.data.number ) = _value;
+
+ return NerdCore::Global::null;
+ }
+ else if (_array.type == NerdCore::Enum::Type::Object || _array.type == NerdCore::Enum::Type::String || _array.type == NerdCore::Enum::Type::Function || _array.type == NerdCore::Enum::Type::Array || _array.type == NerdCore::Enum::Type::Native)
+ {
+ NerdCore::Type::object_t *_obj;
+ if (_array.type == NerdCore::Enum::Type::Object)
+ _obj = &((NerdCore::Class::Object*)_array.data.ptr)->object;
+ else
+ return NerdCore::Global::null;
+
+ return __NERD_Object_Set((std::string)_index, _value, _obj);
+ }
+
+ return NerdCore::Global::null;
+}
+
+
+
+/* typeof */
+const std::string _array[] = {"null", "boolean", "number", "string", "native", "native", "struct", "fixed_array", "array", "object", "function" };
+std::string type_of(NerdCore::Global::var _var)
+{
+ return _array[_var.type];
+}
+std::string typeof(NerdCore::Global::var _var)
+{
+ return _array[_var.type];
+}
\ No newline at end of file
diff --git a/compiler/native/nerdcore/src/objmgmt_header.h b/compiler/native/nerdcore/src/objmgmt_header.h
new file mode 100644
index 000000000..191984921
--- /dev/null
+++ b/compiler/native/nerdcore/src/objmgmt_header.h
@@ -0,0 +1,62 @@
+/*
+ Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
+
+ 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.
+
+*/
+
+NerdCore::VAR __NERD_delete(NerdCore::VAR _left, NerdCore::VAR _right);
+NerdCore::VAR __NERD_Object_Set(std::string _index, NerdCore::VAR _value, NerdCore::Type::object_t *_obj);
+NerdCore::VAR __NERD_Object_Set(NerdCore::VAR _index, NerdCore::VAR _value, NerdCore::VAR _array);
+std::string type_of(NerdCore::Global::var _var);
+std::string typeof(NerdCore::Global::var _var);
+
+
+/*
+inline NerdCore::Global::var Object()
+{
+ return NerdCore::VAR((NerdCore::Class::Object *)new NerdCore::Class::Object());
+}
+*/
+/*
+inline NerdCore::Global::var Object(NerdCore::Type::object_t _obj)
+{
+ return new NerdCore::Class::Object(_obj);
+}
+*/
+
+inline NerdCore::Global::var NewArray()
+{
+ return new NerdCore::Class::Array();
+}
+
+inline NerdCore::Global::var FixedArray()
+{
+ return new NerdCore::Class::FixedArray();
+}
+
+inline NerdCore::Global::var FixedArray(NerdCore::Global::var _length)
+{
+ return new NerdCore::Class::FixedArray(_length);
+}
+
+inline NerdCore::Global::var FixedArray(int _length)
+{
+ return new NerdCore::Class::FixedArray(_length);
+}
\ No newline at end of file
diff --git a/compiler/native/nerdcore/src/operator.h b/compiler/native/nerdcore/src/operator.h
new file mode 100644
index 000000000..67b619703
--- /dev/null
+++ b/compiler/native/nerdcore/src/operator.h
@@ -0,0 +1,879 @@
+/*
+ Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
+
+ 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.
+
+*/
+
+NerdCore::VAR operator+ (const char* _left, const NerdCore::VAR &_right)
+{
+ return NerdCore::VAR(_left) + _right;
+}
+NerdCore::VAR operator+ (std::string _left, const NerdCore::VAR &_right)
+{
+ return NerdCore::VAR(_left) + _right;
+}
+
+NerdCore::VAR operator* (const char* _left, const NerdCore::VAR &_right)
+{
+ return NerdCore::Global::NaN;
+}
+NerdCore::VAR operator* (std::string _left, const NerdCore::VAR &_right)
+{
+ return NerdCore::Global::NaN;
+}
+
+NerdCore::VAR operator- (const char* _left, const NerdCore::VAR &_right)
+{
+ return NerdCore::Global::NaN;
+}
+NerdCore::VAR operator- (std::string _left, const NerdCore::VAR &_right)
+{
+ return NerdCore::Global::NaN;
+}
+
+NerdCore::VAR operator/ (const char* _left, const NerdCore::VAR &_right)
+{
+ return NerdCore::Global::NaN;
+}
+NerdCore::VAR operator/ (std::string _left, const NerdCore::VAR &_right)
+{
+ return NerdCore::Global::NaN;
+}
+
+/*** operator== ***/
+NerdCore::VAR operator== (NerdCore::VAR _left, int right)
+{
+ return (double)_left == right;
+}
+
+NerdCore::VAR operator== (NerdCore::VAR _left, double right)
+{
+ return (double)_left == right;
+}
+
+NerdCore::VAR operator== (NerdCore::VAR _left, std::string right)
+{
+ return (std::string)_left == right;
+}
+
+NerdCore::VAR operator== (NerdCore::VAR _left, const char* right)
+{
+ return (std::string)_left == std::string(right);
+}
+/* end operator== */
+
+/*** operator!= ***/
+NerdCore::VAR operator!= (NerdCore::VAR _left, int right)
+{
+ return (double)_left != right;
+}
+
+NerdCore::VAR operator!= (NerdCore::VAR _left, double right)
+{
+ return (double)_left != right;
+}
+
+NerdCore::VAR operator!= (NerdCore::VAR _left, std::string right)
+{
+ return (std::string)_left != right;
+}
+
+NerdCore::VAR operator!= (NerdCore::VAR _left, const char* right)
+{
+ return (std::string)_left != std::string(right);
+}
+/* end operator!= */
+
+/*** operator| ***/
+NerdCore::VAR operator| (NerdCore::VAR _left, int right)
+{
+ return (int)_left | right;
+}
+
+NerdCore::VAR operator| (NerdCore::VAR _left, double right)
+{
+ return (int)_left | (int)right;
+}
+
+NerdCore::VAR operator| (NerdCore::VAR _left, std::string right)
+{
+ return (double)_left;
+}
+
+NerdCore::VAR operator| (NerdCore::VAR _left, const char* right)
+{
+ return (double)_left;
+}
+/* end operator| */
+
+/*** operator^ ***/
+NerdCore::VAR operator^ (NerdCore::VAR _left, int right)
+{
+ return (int)_left ^ right;
+}
+
+NerdCore::VAR operator^ (NerdCore::VAR _left, double right)
+{
+ return (int)_left ^ (int)right;
+}
+
+NerdCore::VAR operator^ (NerdCore::VAR _left, std::string right)
+{
+ return (double)_left;
+}
+
+NerdCore::VAR operator^ (NerdCore::VAR _left, const char* right)
+{
+ return (double)_left;
+}
+/* end operator^ */
+
+/*** operator& ***/
+NerdCore::VAR operator& (NerdCore::VAR _left, int right)
+{
+ return (int)_left & right;
+}
+
+NerdCore::VAR operator& (NerdCore::VAR _left, double right)
+{
+ return (int)_left & (int)right;
+}
+
+NerdCore::VAR operator& (NerdCore::VAR _left, std::string right)
+{
+ return (double)_left;
+}
+
+NerdCore::VAR operator& (NerdCore::VAR _left, const char* right)
+{
+ return (double)_left;
+}
+/* end operator& */
+
+/*** operator< **
+inline NerdCore::VAR operator< (NerdCore::VAR _left, int right)
+{
+ return _left.data.number < right;
+}
+
+
+inline NerdCore::VAR operator< (NerdCore::VAR _left, double right)
+{
+ return _left.data.number < right;
+}
+*/
+NerdCore::VAR operator< (NerdCore::VAR _left, std::string right)
+{
+ return (std::string)_left < right;
+}
+
+NerdCore::VAR operator< (NerdCore::VAR _left, const char* right)
+{
+ return (std::string)_left < std::string(right);
+}
+/* end operator< */
+
+/*** operator<< ***/
+NerdCore::VAR operator<< (NerdCore::VAR _left, int right)
+{
+ return (int)_left << right;
+}
+
+NerdCore::VAR operator<< (NerdCore::VAR _left, double right)
+{
+ return (int)_left << (int)right;
+}
+
+NerdCore::VAR operator<< (NerdCore::VAR _left, std::string right)
+{
+ return (std::string)_left << right;
+}
+
+NerdCore::VAR operator<< (NerdCore::VAR _left, const char* right)
+{
+ return (std::string)_left << std::string(right);
+}
+/* end operator<< */
+
+/*** operator>= ***/
+NerdCore::VAR operator<= (NerdCore::VAR _left, std::string right)
+{
+ return (std::string)_left <= right;
+}
+
+NerdCore::VAR operator<= (NerdCore::VAR _left, const char* right)
+{
+ return (std::string)_left < std::string(right);
+}
+/* end operator<= */
+
+/*** operator> ***/
+
+NerdCore::VAR operator> (NerdCore::VAR _left, std::string right)
+{
+ return (std::string)_left > right;
+}
+
+NerdCore::VAR operator> (NerdCore::VAR _left, const char* right)
+{
+ return (std::string)_left > std::string(right);
+}
+/* end operator> */
+
+/*** operator>> ***/
+NerdCore::VAR operator>> (NerdCore::VAR _left, int right)
+{
+ return (int)_left >> right;
+}
+
+NerdCore::VAR operator>> (NerdCore::VAR _left, double right)
+{
+ return (int)_left >> (int)right;
+}
+
+NerdCore::VAR operator>> (NerdCore::VAR _left, std::string right)
+{
+ return (std::string)_left >> right;
+}
+
+NerdCore::VAR operator>> (NerdCore::VAR _left, const char* right)
+{
+ return (std::string)_left >> std::string(right);
+}
+/* end operator>> */
+
+/*** operator>= ***/
+
+NerdCore::VAR operator>= (NerdCore::VAR _left, std::string right)
+{
+ return (std::string)_left >= right;
+}
+
+NerdCore::VAR operator>= (NerdCore::VAR _left, const char* right)
+{
+ return (std::string)_left > std::string(right);
+}
+
+/* end operator>= */
+
+NerdCore::VAR __NERD_Boolean_Result(NerdCore::VAR _v)
+{
+ if (_v.type == NerdCore::Enum::Type::Number)
+ return _v.data.number;
+ else if (_v.type == NerdCore::Enum::Type::Boolean)
+ return _v.data.number;
+ else if (_v.type == NerdCore::Enum::Type::String)
+ {
+ if (strlen(((NerdCore::Class::String*)_v.data.ptr)->value.c_str()) > 0)
+ return true;
+ else
+ return false;
+ }
+ else if (_v.type == NerdCore::Enum::Type::Array)
+ return true;
+ else
+ return false;
+}
+
+std::string __NERD_DOUBLE_TO_STRING(double _var)
+{
+ std::ostringstream strout ;
+ strout << std::fixed << std::setprecision(14) << _var;
+ std::string str = strout.str() ;
+
+ size_t end = str.find_last_not_of( '0' ) + 1 ;
+ str = str.erase( end ) ;
+
+ end = str.find_last_not_of( '.' ) + 1 ;
+ str = str.erase( end ) ;
+
+ int exp = str.length();
+ if(exp > 21)
+ {
+ std::string first = str.substr(0, 1);
+ std::string second = str.substr(1, 15);
+ str = first + "." + second + "e+" + std::to_string(exp-1);
+ }
+ return str;
+}
+
+std::ostream &operator<<(std::ostream &os, const NerdCore::VAR &_v)
+{
+ switch (_v.type)
+ {
+ case NerdCore::Enum::Type::Boolean:
+ if(_v.data.number) os << "true";
+ else os << "false";
+ break;
+ case NerdCore::Enum::Type::Number:
+ os << std::setprecision(14) << _v.data.number;
+ break;
+ case NerdCore::Enum::Type::String:
+ os << (std::string)(*(NerdCore::Class::String*)_v.data.ptr);
+ break;
+ case NerdCore::Enum::Type::Object:
+ os << __NERD_Object_Stringify(_v);
+ break;
+ case NerdCore::Enum::Type::FixedArray:
+ os << __NERD_Object_Stringify(_v);
+ break;
+ case NerdCore::Enum::Type::Array:
+ os << __NERD_Object_Stringify(_v);
+ break;
+ case NerdCore::Enum::Type::Struct:
+ os << (std::string)(*(NerdCore::Class::Struct*)_v.data.ptr);
+ break;
+ case NerdCore::Enum::Type::Native:
+ os << (std::string)(*(NerdCore::Class::Native*)_v.data.ptr);
+ break;
+ case NerdCore::Enum::Type::Function:
+ os << (std::string)(*(NerdCore::Class::Function*)_v.data.ptr);
+ break;
+ case NerdCore::Enum::Type::Null:
+ os << "null";
+ break;
+ default:
+ os << "null";
+ break;
+ }
+ return os;
+
+}
+
+NerdCore::VAR parseInt(NerdCore::VAR _str)
+{
+ if (_str.type == NerdCore::Enum::Type::String)
+ {
+#ifdef __NERD_ENV_ARDUINO
+ return NerdCore::Global::null;
+#else
+ return __NERD_Create_Number((double)(*(NerdCore::Class::String*)_str.data.ptr));
+#endif
+ }
+ else
+ return NerdCore::Global::null;
+}
+
+NerdCore::VAR __NERD_Log_Console(NerdCore::VAR _var)
+{
+#ifdef __NERD_ENV_ARDUINO
+
+#else
+ std::cout << _var;
+ std::cout << std::endl;
+#endif
+
+ return NerdCore::Global::null;
+}
+
+NerdCore::VAR __NERD_Log_Console(NerdCore::VAR* _var, int _length)
+{
+#ifdef __NERD_ENV_ARDUINO
+
+#else
+ bool first = false;
+ for(int i = 0; i < _length; i++)
+ {
+ if(first) std::cout << " ";
+ std::cout << _var[i];
+ if(!first) first = true;
+ }
+ std::cout << std::endl;
+#endif
+
+ return NerdCore::Global::null;
+}
+
+NerdCore::VAR __NERD_Object_Keys(NerdCore::VAR _var)
+{
+ NerdCore::VAR _res = new NerdCore::Class::Array();
+
+ if (_var.type != NerdCore::Enum::Type::Object && _var.type != NerdCore::Enum::Type::Array)
+ {
+ return _res;
+ }
+
+ if(_var.type == NerdCore::Enum::Type::Array)
+ {
+ NerdCore::Type::vector_t *_arr = &((NerdCore::Class::Array*)_var.data.ptr)->value;
+ int _j = (*_arr).size();
+ for (int _i = 0; _i < _j; _i++)
+ {
+ _res[_i] = std::to_string(_i);
+ }
+ }
+ else
+ {
+ NerdCore::Type::object_t *_obj;
+ if(_var.type == NerdCore::Enum::Type::Object) _obj = &((NerdCore::Class::Object*)_var.data.ptr)->object;
+
+ #ifndef __NERD__OBJECT_VECTOR
+ int _k = 0;
+ for (auto _el: *_obj)
+ {
+ _res[_k] = _el.first;
+ _k++;
+ }
+ #else
+ int _j = (*_obj).size();
+ for (int _k = 0; _k < _j; _k++)
+ {
+ _res[_k] = (*_obj)[_k].first;
+ }
+ #endif
+ }
+ return _res;
+}
+
+NerdCore::VAR __NERD_Object_Stringify(NerdCore::VAR _var)
+{
+ return __NERD_Object_Stringify(_var, true);
+}
+
+NerdCore::VAR __NERD_Object_Stringify(NerdCore::VAR _var, bool _bracket)
+{
+ NerdCore::Enum::Type _t = _var.type;
+ if (_t == NerdCore::Enum::Type::Number)
+ {
+ return "\e[33m" + _var + "\e[0m";
+ }
+ else if (_t == NerdCore::Enum::Type::String)
+ {
+ return "\e[32m'" + ((NerdCore::Class::String*)_var.data.ptr)->value + "'\e[0m";
+ }
+ else if (_t == NerdCore::Enum::Type::Function)
+ {
+ return "'" + (std::string)(*(NerdCore::Class::Function*)_var.data.ptr) + "'";
+ }
+ else if (_t == NerdCore::Enum::Type::FixedArray)
+ {
+ NerdCore::VAR _res = "";
+ NerdCore::VAR *_arr = ((NerdCore::Class::FixedArray*)_var.data.ptr)->value;
+
+ if(_bracket) _res += " [ ";
+ int j = ((NerdCore::Class::FixedArray*)_var.data.ptr)->length;
+ int k = 0;
+ int l = 0;
+ for (int i = 0; i < j; i++)
+ {
+ if (l > 0) _res += ", ";
+ if(k > 0)
+ {
+ if(k == 1)
+ _res += "\e[90m<1 empty item>\e[0m, ";
+ else
+ _res += "\e[90m<" + std::to_string(k) + " empty items>\e[0m, ";
+ k = 0;
+ }
+ _res += __NERD_Object_Stringify((*_arr)[i], _bracket);
+ l++;
+ }
+
+ if(k > 0)
+ {
+ if (l > 0) _res += ", ";
+ if(k == 1)
+ _res += "\e[90m<1 empty item>\e[0m";
+ else
+ _res += "\e[90m<" + std::to_string(k) + " empty items>\e[0m";
+ l++;
+ }
+
+ if(_bracket) _res += " ] ";
+
+ return _res;
+ }
+ else if (_t == NerdCore::Enum::Type::Array)
+ {
+ NerdCore::VAR _res = NerdCore::Global::var("");
+ NerdCore::Type::vector_t *_arr = &((NerdCore::Class::Array*)_var.data.ptr)->value;
+ if(_bracket) _res += " [ ";
+ int j = (*_arr).size();
+ int k = 0;
+ int l = 0;
+ for (int i = 0; i < j; i++)
+ {
+ if (l > 0) _res += ", ";
+ if(k > 0)
+ {
+ if(k == 1)
+ _res += "\e[90m<1 empty item>\e[0m, ";
+ else
+ _res += "\e[90m<" + std::to_string(k) + " empty items>\e[0m, ";
+ k = 0;
+ }
+
+ NerdCore::Global::var test =
+ _res += __NERD_Object_Stringify((*_arr)[i], _bracket);
+
+ l++;
+ }
+ if(k > 0)
+ {
+ if (l > 0) _res += ", ";
+ if(k == 1)
+ _res += "\e[90m<1 empty item>\e[0m";
+ else
+ _res += "\e[90m<" + std::to_string(k) + " empty items>\e[0m";
+ l++;
+ }
+
+ if(_bracket) _res += " ] ";
+
+ return _res;
+ }
+ else if (_t == NerdCore::Enum::Type::Object)
+ {
+ NerdCore::VAR _res = "";
+ NerdCore::Type::object_t *_obj = &((NerdCore::Class::Object*)_var.data.ptr)->object;
+ _res = "{";
+ #ifndef __NERD__OBJECT_VECTOR
+ int _i = 0;
+ int _comma = 0;
+ for (auto _el: *_obj)
+ {
+ if(_el.second.type != NerdCore::Enum::Type::Null && _el.first != "__proto__" && _el.first != "prototype")
+ {
+ if (_comma > 0) _res += ", ";
+ _res += NerdCore::VAR("\"") + _el.first + "\"";
+ _res += ":";
+ _res += __NERD_Object_Stringify(_el.second);
+ _comma++;
+ }
+ _i++;
+ }
+ #else
+ int j = (*_obj).size();
+ for (int _i = 0; _i < j; _i++)
+ {
+ if (_i > 0) _res += ", ";
+ _res += NerdCore::VAR("\"") + (*_obj)[_i].first + "\"";
+ _res += ":";
+ _res += __NERD_Object_Stringify((*_obj)[_i].second);
+ }
+ #endif
+ _res += "}";
+ return _res;
+ }
+ else
+ return "";
+}
+
+NerdCore::VAR __NERD_Object_Clone(NerdCore::VAR& _var)
+{
+ NerdCore::Enum::Type _t = _var.type;
+ switch(_t)
+ {
+ case NerdCore::Enum::Type::Null:
+ case NerdCore::Enum::Type::Number:
+ case NerdCore::Enum::Type::String:
+ case NerdCore::Enum::Type::Function:
+ return _var;
+ case NerdCore::Enum::Type::Array:
+ {
+ NerdCore::VAR _res = new NerdCore::Class::Array();
+ std::vector *_arr = &((NerdCore::Class::Array*)_var.data.ptr)->value;
+
+ int j = (*_arr).size();
+ for (int i = 0; i < j; i++)
+ {
+ _res[i] = __NERD_Object_Clone((*_arr)[i]);
+ }
+ return _res;
+ }
+ case NerdCore::Enum::Type::Object:
+ {
+ const NerdCore::VAR _res = new NerdCore::Class::Object();
+ NerdCore::Type::object_t *_obj = &((NerdCore::Class::Object*)_var.data.ptr)->object;
+ #ifndef __NERD__OBJECT_VECTOR
+ for (auto _el: *_obj)
+ {
+ _res[_el.first] = __NERD_Object_Clone(_el.second);
+ }
+ #else
+ int j = (*_obj).size();
+ for (int _i = 0; _i < j; _i++)
+ {
+ _res[(*_obj)[_i].first] = __NERD_Object_Clone((*_obj)[_i].second);
+ }
+ #endif
+ return _res;
+ }
+ default:
+ return NerdCore::Global::null;
+ }
+}
+
+void __NERD_Object_Construct(NerdCore::VAR _this, NerdCore::VAR _prototype)
+{
+ if(_this.type == NerdCore::Enum::Type::Object && _prototype.type == NerdCore::Enum::Type::Object)
+ {
+ NerdCore::Type::object_t *_obj = &((NerdCore::Class::Object*)_prototype.data.ptr)->object;
+
+ #ifndef __NERD__OBJECT_VECTOR
+ for (auto _el: *_obj)
+ {
+ NerdCore::VAR _tmp = _this[_el.first];
+ if(_tmp.type == NerdCore::Enum::Type::Null)
+ {
+ _this[_el.first] = _el.second;
+ }
+ }
+ #else
+ int j = (*_obj).size();
+ for (int _i = 0; _i < j; _i++)
+ {
+ NerdCore::VAR _tmp = _this[(*_obj)[_i].first];
+ if(_tmp.type == NerdCore::Enum::Type::Null)
+ {
+ _this[(*_obj)[_i].first] = (*_obj)[_i].second;
+ }
+ }
+ #endif
+ }
+
+}
+
+NerdCore::VAR __NERD_CREATE_Function(void *_fn)
+{
+ return NerdCore::VAR(NerdCore::Enum::Type::Function, _fn);
+}
+
+NerdCore::VAR __NERD_Create_Native(void *_native)
+{
+ return NerdCore::VAR(NerdCore::Enum::Type::Null, _native);
+}
+
+void *__NERD_Get_Native(NerdCore::VAR _native)
+{
+ return ((NerdCore::Class::Function*)_native.data.ptr);
+}
+
+__NERD_Create_Lambda(__IMPL_EVAL)
+{
+ __NERD_Log_Console("eval not implemented, return NerdCore::Global::null");
+ return NerdCore::VAR();
+});
+
+NerdCore::VAR eval = __NERD_Create_Function(__IMPL_EVAL);
+
+std::function *__NERD_IS_NAN = new std::function([](NerdCore::Type::vector_t _Nerd_VARARGS) {
+ NerdCore::VAR _test;
+ if (_Nerd_VARARGS.size() > 0)
+ _test = _Nerd_VARARGS[0];
+ else
+ return __NERD_Create_Boolean(0);
+
+ if (_test.type == NerdCore::Enum::Type::Number)
+ {
+ return __NERD_Create_Boolean(1);
+ }
+
+ return __NERD_Create_Boolean(0);
+});
+
+NerdCore::VAR isNaN = NerdCore::VAR(NerdCore::Enum::Type::Function, __NERD_IS_NAN);
+
+NerdCore::VAR __NERD_EQUAL_VALUE_AND_TYPE(NerdCore::VAR _left, NerdCore::VAR _right)
+{
+ if (_left.type == _right.type && (NerdCore::VAR)_left == (NerdCore::VAR)_right)
+ {
+ return __NERD_Create_Boolean(1);
+ }
+
+ return __NERD_Create_Boolean(0);
+}
+
+NerdCore::VAR __NERD_NOT_EQUAL_VALUE_AND_TYPE(NerdCore::VAR _left, NerdCore::VAR _right)
+{
+ if (_left.type != _right.type || (bool)(_left != _right))
+ {
+ return __NERD_Create_Boolean(1);
+ }
+
+ return __NERD_Create_Boolean(0);
+}
+
+NerdCore::VAR operator+ (NerdCore::VAR _left, int right)
+{
+ if (_left.type == NerdCore::Enum::Type::String) return (std::string)_left + __NERD_DOUBLE_TO_STRING(right);
+ else return (double)_left + right;
+}
+
+NerdCore::VAR operator+ (NerdCore::VAR _left, double right)
+{
+ if (_left.type == NerdCore::Enum::Type::String) return (std::string)_left + __NERD_DOUBLE_TO_STRING(right);
+ else return (double)_left + right;
+}
+
+NerdCore::VAR operator+ (NerdCore::VAR _left, const char* right)
+{
+ return (std::string)_left + std::string(right);
+}
+
+void operator+= (NerdCore::VAR& _left, std::string right)
+{
+ std::string _str = (std::string)_left;
+ _str += right;
+ _left = _str;
+}
+
+void operator+= (NerdCore::VAR& _left, const char* right)
+{
+ std::string _str = (std::string)_left;
+ _str += right;
+ _left = _str;
+}
+
+void operator+= (NerdCore::VAR& _left, int right)
+{
+ if(_left.type == NerdCore::Enum::Type::Number) _left.data.number += right;
+ else
+ {
+ std::string _str = (std::string)_left;
+ _str += right;
+ _left = _str;
+ }
+}
+
+void operator+= (NerdCore::VAR& _left, double right)
+{
+ if(_left.type == NerdCore::Enum::Type::Number) _left.data.number += right;
+ else
+ {
+ std::string _str = (std::string)_left;
+ _str += right;
+ _left.data.ptr = new NerdCore::Class::String(_str);
+ _left.type = NerdCore::Enum::Type::String;
+ }
+}
+
+
+NerdCore::VAR operator|| (NerdCore::VAR _left, int right)
+{
+ if(_left.type != NerdCore::Enum::Type::Null) return _left;
+ else return right;
+}
+
+NerdCore::VAR operator|| (NerdCore::VAR _left, double right)
+{
+ if(_left.type != NerdCore::Enum::Type::Null) return _left;
+ else return right;
+}
+
+NerdCore::VAR operator|| (NerdCore::VAR _left, std::string right)
+{
+ if(_left.type != NerdCore::Enum::Type::Null) return _left;
+ else return right;
+}
+
+NerdCore::VAR operator|| (NerdCore::VAR _left, const char* right)
+{
+ if(_left.type != NerdCore::Enum::Type::Null) return _left;
+ else return right;
+}
+
+/*** op* ***/
+NerdCore::VAR operator* (NerdCore::VAR _left, int right)
+{
+ return (double)_left * right;
+}
+
+NerdCore::VAR operator* (NerdCore::VAR _left, double right)
+{
+ return (double)_left * right;
+}
+
+NerdCore::VAR operator* (NerdCore::VAR _left, std::string right)
+{
+ return (double)_left * (double)(NerdCore::VAR(right));
+}
+
+NerdCore::VAR operator* (NerdCore::VAR _left, const char* right)
+{
+ return (double)_left * (double)(NerdCore::VAR(right));
+}
+/* end op* */
+
+/*** op- ***/
+NerdCore::VAR operator- (NerdCore::VAR _left, int right)
+{
+ return (double)_left - right;
+}
+
+NerdCore::VAR operator- (NerdCore::VAR _left, double right)
+{
+ return (double)_left - right;
+}
+
+NerdCore::VAR operator- (NerdCore::VAR _left, std::string right)
+{
+ return (double)_left - (double)(NerdCore::VAR(right));
+}
+
+NerdCore::VAR operator- (NerdCore::VAR _left, const char* right)
+{
+ return (double)_left - (double)(NerdCore::VAR(right));
+}
+/* end op- */
+
+/*** op/ ***/
+NerdCore::VAR operator/ (NerdCore::VAR _left, int right)
+{
+ return (double)_left / right;
+}
+
+NerdCore::VAR operator/ (NerdCore::VAR _left, double right)
+{
+ return (double)_left / right;
+}
+
+NerdCore::VAR operator/ (NerdCore::VAR _left, std::string right)
+{
+ return (double)_left / (double)(NerdCore::VAR(right));
+}
+
+NerdCore::VAR operator/ (NerdCore::VAR _left, const char* right)
+{
+ return (double)_left / (double)(NerdCore::VAR(right));
+}
+/* end op/ */
+
+/*** op% ***/
+NerdCore::VAR operator% (NerdCore::VAR _left, int right)
+{
+ return (int)_left % right;
+}
+
+NerdCore::VAR operator% (NerdCore::VAR _left, double right)
+{
+ return (int)_left % (int)right;
+}
+
+NerdCore::VAR operator% (NerdCore::VAR _left, std::string right)
+{
+ return (int)_left % (int)(NerdCore::VAR(right));
+}
+
+NerdCore::VAR operator% (NerdCore::VAR _left, const char* right)
+{
+ return (int)_left % (int)(NerdCore::VAR(right));
+}
+/* end op% */
\ No newline at end of file
diff --git a/compiler/native/nerdcore/src/operator_header.h b/compiler/native/nerdcore/src/operator_header.h
new file mode 100644
index 000000000..b99d7def5
--- /dev/null
+++ b/compiler/native/nerdcore/src/operator_header.h
@@ -0,0 +1,214 @@
+/*
+ Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
+
+ 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.
+
+*/
+#ifdef __NERD_ENV_ARDUINO
+ bool operator==(std::string_view sw, const char* c)
+ {
+ return sw == std::string_view(c);
+ }
+
+ bool operator!=(std::string_view sw, const char* c)
+ {
+ return sw != std::string_view(c);
+ }
+#else
+ constexpr bool operator==(std::string_view sw, const char* c)
+ {
+ return sw == std::string_view(c);
+ }
+
+ constexpr bool operator!=(std::string_view sw, const char* c)
+ {
+ return sw != std::string_view(c);
+ }
+#endif
+
+NerdCore::VAR __NERD_Boolean_Result(NerdCore::VAR _v);
+std::string __NERD_DOUBLE_TO_STRING(double _var);
+std::ostream &operator<<(std::ostream &os, const NerdCore::VAR &_v);
+NerdCore::VAR parseInt(NerdCore::VAR _str);
+NerdCore::VAR __NERD_Log_Console(NerdCore::VAR _var);
+NerdCore::VAR __NERD_Log_Console(NerdCore::VAR* _var, int _length);
+NerdCore::VAR __NERD_Object_Keys(NerdCore::VAR _var);
+NerdCore::VAR __NERD_Object_Stringify(NerdCore::VAR _var);
+NerdCore::VAR __NERD_Object_Stringify(NerdCore::VAR _var, bool _bracket);
+NerdCore::VAR __NERD_Object_Clone(NerdCore::VAR& _var);
+void __NERD_Object_Construct(NerdCore::VAR _this, NerdCore::VAR _prototype);
+NerdCore::VAR __NERD_CREATE_Function(void *_fn);
+NerdCore::VAR __NERD_Create_Native(void *_native);
+void *__NERD_Get_Native(NerdCore::VAR _native);
+
+/*** REDIFINING STD OPERATORS ***/
+
+NerdCore::VAR operator+ (const char* _left, const NerdCore::VAR &_right);
+NerdCore::VAR operator+ (std::string _left, const NerdCore::VAR &_right);
+
+NerdCore::VAR operator- (const char* _left, const NerdCore::VAR &_right);
+NerdCore::VAR operator- (std::string _left, const NerdCore::VAR &_right);
+
+NerdCore::VAR operator* (const char* _left, const NerdCore::VAR &_right);
+NerdCore::VAR operator* (std::string _left, const NerdCore::VAR &_right);
+
+NerdCore::VAR operator/ (const char* _left, const NerdCore::VAR &_right);
+NerdCore::VAR operator/ (std::string _left, const NerdCore::VAR &_right);
+
+
+inline bool operator< (NerdCore::VAR _left, const int right) noexcept
+{
+ return _left.data.number < right;
+}
+inline bool operator< (NerdCore::VAR _left, const long long int right) noexcept
+{
+ return _left.data.number < right;
+}
+inline bool operator< (NerdCore::VAR _left, const double right) noexcept
+{
+ return _left.data.number < right;
+}
+
+NerdCore::VAR operator< (NerdCore::VAR _left, std::string right);
+NerdCore::VAR operator< (NerdCore::VAR _left, const char* right);
+
+inline bool operator<= (NerdCore::VAR _left, const int right) noexcept
+{
+ return _left.data.number <= right;
+}
+inline bool operator<= (NerdCore::VAR _left, const long long int right) noexcept
+{
+ return _left.data.number <= right;
+}
+inline bool operator<= (NerdCore::VAR _left, const double right) noexcept
+{
+ return _left.data.number <= right;
+}
+
+NerdCore::VAR operator<= (NerdCore::VAR _left, std::string right);
+NerdCore::VAR operator<= (NerdCore::VAR _left, const char* right);
+
+inline bool operator> (NerdCore::VAR _left, const int right) noexcept
+{
+ return _left.data.number > right;
+}
+inline bool operator> (NerdCore::VAR _left, const long long int right) noexcept
+{
+ return _left.data.number > right;
+}
+inline bool operator> (NerdCore::VAR _left, const double right) noexcept
+{
+ return _left.data.number > right;
+}
+
+NerdCore::VAR operator> (NerdCore::VAR _left, std::string right);
+NerdCore::VAR operator> (NerdCore::VAR _left, const char* right);
+
+inline const bool operator>= (NerdCore::VAR _left, const int right) noexcept
+{
+ return _left.data.number >= right;
+}
+inline bool operator>= (NerdCore::VAR _left, const long long int right) noexcept
+{
+ return _left.data.number >= right;
+}
+inline bool operator>= (NerdCore::VAR _left, const double right) noexcept
+{
+ return _left.data.number >= right;
+}
+
+NerdCore::VAR operator>= (NerdCore::VAR _left, std::string right);
+NerdCore::VAR operator>= (NerdCore::VAR _left, const char* right);
+
+
+/*** END REDIFINING STD OPERATORS ***/
+
+extern NerdCore::VAR eval;
+extern std::function *__NERD_IS_NAN;
+extern NerdCore::VAR isNaN;
+
+NerdCore::VAR __NERD_EQUAL_VALUE_AND_TYPE(NerdCore::VAR _left, NerdCore::VAR _right);
+NerdCore::VAR __NERD_NOT_EQUAL_VALUE_AND_TYPE(NerdCore::VAR _left, NerdCore::VAR _right);
+NerdCore::VAR operator+ (NerdCore::VAR _left, int right);
+NerdCore::VAR operator+ (NerdCore::VAR _left, double right);
+
+void operator+= (NerdCore::VAR& _left, std::string right);
+void operator+= (NerdCore::VAR& _left, const char* right);
+void operator+= (NerdCore::VAR& _left, int right);
+void operator+= (NerdCore::VAR& _left, double right);
+
+NerdCore::VAR operator* (NerdCore::VAR _left, int right);
+NerdCore::VAR operator* (NerdCore::VAR _left, double right);
+NerdCore::VAR operator* (NerdCore::VAR _left, std::string right);
+NerdCore::VAR operator* (NerdCore::VAR _left, const char* right);
+
+NerdCore::VAR operator- (NerdCore::VAR _left, int right);
+NerdCore::VAR operator- (NerdCore::VAR _left, double right);
+NerdCore::VAR operator- (NerdCore::VAR _left, std::string right);
+NerdCore::VAR operator- (NerdCore::VAR _left, const char* right);
+
+NerdCore::VAR operator/ (NerdCore::VAR _left, int right);
+NerdCore::VAR operator/ (NerdCore::VAR _left, double right);
+NerdCore::VAR operator/ (NerdCore::VAR _left, std::string right);
+NerdCore::VAR operator/ (NerdCore::VAR _left, const char* right);
+
+NerdCore::VAR operator% (NerdCore::VAR _left, int right);
+NerdCore::VAR operator% (NerdCore::VAR _left, double right);
+NerdCore::VAR operator% (NerdCore::VAR _left, std::string right);
+NerdCore::VAR operator% (NerdCore::VAR _left, const char* right);
+
+NerdCore::VAR operator|| (NerdCore::VAR _left, int right);
+NerdCore::VAR operator|| (NerdCore::VAR _left, double right);
+NerdCore::VAR operator|| (NerdCore::VAR _left, std::string right);
+NerdCore::VAR operator|| (NerdCore::VAR _left, const char* right);
+
+NerdCore::VAR operator== (NerdCore::VAR _left, int right);
+NerdCore::VAR operator== (NerdCore::VAR _left, double right);
+NerdCore::VAR operator== (NerdCore::VAR _left, std::string right);
+NerdCore::VAR operator== (NerdCore::VAR _left, const char* right);
+
+NerdCore::VAR operator!= (NerdCore::VAR _left, int right);
+NerdCore::VAR operator!= (NerdCore::VAR _left, double right);
+NerdCore::VAR operator!= (NerdCore::VAR _left, std::string right);
+NerdCore::VAR operator!= (NerdCore::VAR _left, const char* right);
+
+NerdCore::VAR operator| (NerdCore::VAR _left, int right);
+NerdCore::VAR operator| (NerdCore::VAR _left, double right);
+NerdCore::VAR operator| (NerdCore::VAR _left, std::string right);
+NerdCore::VAR operator| (NerdCore::VAR _left, const char* right);
+
+NerdCore::VAR operator^ (NerdCore::VAR _left, int right);
+NerdCore::VAR operator^ (NerdCore::VAR _left, double right);
+NerdCore::VAR operator^ (NerdCore::VAR _left, std::string right);
+NerdCore::VAR operator^ (NerdCore::VAR _left, const char* right);
+
+NerdCore::VAR operator& (NerdCore::VAR _left, int right);
+NerdCore::VAR operator& (NerdCore::VAR _left, double right);
+NerdCore::VAR operator& (NerdCore::VAR _left, std::string right);
+NerdCore::VAR operator& (NerdCore::VAR _left, const char* right);
+
+NerdCore::VAR operator<< (NerdCore::VAR _left, int right);
+NerdCore::VAR operator<< (NerdCore::VAR _left, double right);
+NerdCore::VAR operator<< (NerdCore::VAR _left, std::string right);
+NerdCore::VAR operator<< (NerdCore::VAR _left, const char* right);
+
+NerdCore::VAR operator>> (NerdCore::VAR _left, int right);
+NerdCore::VAR operator>> (NerdCore::VAR _left, double right);
+NerdCore::VAR operator>> (NerdCore::VAR _left, std::string right);
+NerdCore::VAR operator>> (NerdCore::VAR _left, const char* right);
diff --git a/compiler/native/nerdcore/src/stdfn.h b/compiler/native/nerdcore/src/stdfn.h
new file mode 100644
index 000000000..fa137ab07
--- /dev/null
+++ b/compiler/native/nerdcore/src/stdfn.h
@@ -0,0 +1,96 @@
+/*
+ Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
+
+ 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.
+
+*/
+
+namespace NerdCore::Functions
+{
+ NerdCore::VAR println()
+ {
+ #ifndef __NERD_ENV_ARDUINO
+ std::cout << std::endl;
+ #endif
+ return NerdCore::Global::null;
+ }
+ NerdCore::VAR println(NerdCore::VAR _var)
+ {
+ #ifndef __NERD_ENV_ARDUINO
+ std::cout << _var << std::endl;
+ #endif
+ return NerdCore::Global::null;
+ }
+
+ NerdCore::VAR print()
+ {
+ return NerdCore::Global::null;
+ }
+
+ NerdCore::VAR print(NerdCore::VAR _var)
+ {
+ #ifndef __NERD_ENV_ARDUINO
+ std::cout << _var;
+ #endif
+ return NerdCore::Global::null;
+ }
+
+
+}
+
+ // no namespace
+ NerdCore::VAR length_of(NerdCore::VAR _var)
+ {
+ switch( _var.type)
+ {
+ case NerdCore::Enum::Type::Null:
+ return 0;
+ break;
+ case NerdCore::Enum::Type::Boolean:
+ return 1;
+ break;
+ case NerdCore::Enum::Type::Number:
+ return 1;
+ break;
+ case NerdCore::Enum::Type::String:
+ return (double)((std::string)_var).size();
+ break;
+ case NerdCore::Enum::Type::Array:
+ return (double)((NerdCore::Class::Array*)_var.data.ptr)->Size();
+ break;
+ case NerdCore::Enum::Type::FixedArray:
+ return (double)((NerdCore::Class::FixedArray*)_var.data.ptr)->length;
+ break;
+ case NerdCore::Enum::Type::Object:
+ return (double)((NerdCore::Class::Object*)_var.data.ptr)->Size();
+ break;
+ case NerdCore::Enum::Type::Native:
+ return (double)((NerdCore::Class::Native*)_var.data.ptr)->length;
+ break;
+ default:
+ return 0;
+ break;
+ }
+ return 0;
+ }
+
+ NerdCore::VAR size_of(NerdCore::VAR _var)
+ {
+ return (double)sizeof(_var);
+ }
\ No newline at end of file
diff --git a/compiler/native/nerdcore/src/stdfn_header.h b/compiler/native/nerdcore/src/stdfn_header.h
new file mode 100644
index 000000000..b04bcc3de
--- /dev/null
+++ b/compiler/native/nerdcore/src/stdfn_header.h
@@ -0,0 +1,34 @@
+/*
+ Copyright (c) 2021 NerdLang - Adrien THIERRY and contributors
+
+ 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.
+
+*/
+
+namespace NerdCore::Functions
+{
+ NerdCore::VAR println();
+ NerdCore::VAR println(NerdCore::VAR _var);
+ NerdCore::VAR print();
+ NerdCore::VAR print(NerdCore::VAR _var);
+}
+
+ // no namespace
+ NerdCore::VAR length_of(NerdCore::VAR _var);
+ NerdCore::VAR size_of(NerdCore::VAR _var);
\ No newline at end of file
diff --git a/compiler/native/nerdcore/src/tsl/robin_growth_policy.h b/compiler/native/nerdcore/src/tsl/robin_growth_policy.h
new file mode 100644
index 000000000..eba8cdfa0
--- /dev/null
+++ b/compiler/native/nerdcore/src/tsl/robin_growth_policy.h
@@ -0,0 +1,406 @@
+/**
+ * MIT License
+ *
+ * Copyright (c) 2017 Thibaut Goetghebuer-Planchon
+ *
+ * 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.
+ */
+#ifndef TSL_ROBIN_GROWTH_POLICY_H
+#define TSL_ROBIN_GROWTH_POLICY_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#ifdef TSL_DEBUG
+#define tsl_rh_assert(expr) assert(expr)
+#else
+#define tsl_rh_assert(expr) (static_cast(0))
+#endif
+
+/**
+ * If exceptions are enabled, throw the exception passed in parameter, otherwise
+ * call std::terminate.
+ */
+#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || \
+ (defined(_MSC_VER) && defined(_CPPUNWIND))) && \
+ !defined(TSL_NO_EXCEPTIONS)
+#define TSL_RH_THROW_OR_TERMINATE(ex, msg) throw ex(msg)
+#else
+#define TSL_RH_NO_EXCEPTIONS
+#ifdef TSL_DEBUG
+#include
+#define TSL_RH_THROW_OR_TERMINATE(ex, msg) \
+ do { \
+ std::cerr << msg << std::endl; \
+ std::terminate(); \
+ } while (0)
+#else
+#define TSL_RH_THROW_OR_TERMINATE(ex, msg) std::terminate()
+#endif
+#endif
+
+#if defined(__GNUC__) || defined(__clang__)
+#define TSL_RH_LIKELY(exp) (__builtin_expect(!!(exp), true))
+#else
+#define TSL_RH_LIKELY(exp) (exp)
+#endif
+
+#define TSL_RH_UNUSED(x) static_cast(x)
+
+namespace tsl {
+namespace rh {
+
+/**
+ * Grow the hash table by a factor of GrowthFactor keeping the bucket count to a
+ * power of two. It allows the table to use a mask operation instead of a modulo
+ * operation to map a hash to a bucket.
+ *
+ * GrowthFactor must be a power of two >= 2.
+ */
+template
+class power_of_two_growth_policy {
+ public:
+ /**
+ * Called on the hash table creation and on rehash. The number of buckets for
+ * the table is passed in parameter. This number is a minimum, the policy may
+ * update this value with a higher value if needed (but not lower).
+ *
+ * If 0 is given, min_bucket_count_in_out must still be 0 after the policy
+ * creation and bucket_for_hash must always return 0 in this case.
+ */
+ explicit power_of_two_growth_policy(std::size_t& min_bucket_count_in_out) {
+ if (min_bucket_count_in_out > max_bucket_count()) {
+ TSL_RH_THROW_OR_TERMINATE(std::length_error,
+ "The hash table exceeds its maximum size.");
+ }
+
+ if (min_bucket_count_in_out > 0) {
+ min_bucket_count_in_out =
+ round_up_to_power_of_two(min_bucket_count_in_out);
+ m_mask = min_bucket_count_in_out - 1;
+ } else {
+ m_mask = 0;
+ }
+ }
+
+ /**
+ * Return the bucket [0, bucket_count()) to which the hash belongs.
+ * If bucket_count() is 0, it must always return 0.
+ */
+ std::size_t bucket_for_hash(std::size_t hash) const noexcept {
+ return hash & m_mask;
+ }
+
+ /**
+ * Return the number of buckets that should be used on next growth.
+ */
+ std::size_t next_bucket_count() const {
+ if ((m_mask + 1) > max_bucket_count() / GrowthFactor) {
+ TSL_RH_THROW_OR_TERMINATE(std::length_error,
+ "The hash table exceeds its maximum size.");
+ }
+
+ return (m_mask + 1) * GrowthFactor;
+ }
+
+ /**
+ * Return the maximum number of buckets supported by the policy.
+ */
+ std::size_t max_bucket_count() const {
+ // Largest power of two.
+ return (std::numeric_limits::max() / 2) + 1;
+ }
+
+ /**
+ * Reset the growth policy as if it was created with a bucket count of 0.
+ * After a clear, the policy must always return 0 when bucket_for_hash is
+ * called.
+ */
+ void clear() noexcept { m_mask = 0; }
+
+ private:
+ static std::size_t round_up_to_power_of_two(std::size_t value) {
+ if (is_power_of_two(value)) {
+ return value;
+ }
+
+ if (value == 0) {
+ return 1;
+ }
+
+ --value;
+ for (std::size_t i = 1; i < sizeof(std::size_t) * CHAR_BIT; i *= 2) {
+ value |= value >> i;
+ }
+
+ return value + 1;
+ }
+
+ static constexpr bool is_power_of_two(std::size_t value) {
+ return value != 0 && (value & (value - 1)) == 0;
+ }
+
+ protected:
+ static_assert(is_power_of_two(GrowthFactor) && GrowthFactor >= 2,
+ "GrowthFactor must be a power of two >= 2.");
+
+ std::size_t m_mask;
+};
+
+/**
+ * Grow the hash table by GrowthFactor::num / GrowthFactor::den and use a modulo
+ * to map a hash to a bucket. Slower but it can be useful if you want a slower
+ * growth.
+ */
+template >
+class mod_growth_policy {
+ public:
+ explicit mod_growth_policy(std::size_t& min_bucket_count_in_out) {
+ if (min_bucket_count_in_out > max_bucket_count()) {
+ TSL_RH_THROW_OR_TERMINATE(std::length_error,
+ "The hash table exceeds its maximum size.");
+ }
+
+ if (min_bucket_count_in_out > 0) {
+ m_mod = min_bucket_count_in_out;
+ } else {
+ m_mod = 1;
+ }
+ }
+
+ std::size_t bucket_for_hash(std::size_t hash) const noexcept {
+ return hash % m_mod;
+ }
+
+ std::size_t next_bucket_count() const {
+ if (m_mod == max_bucket_count()) {
+ TSL_RH_THROW_OR_TERMINATE(std::length_error,
+ "The hash table exceeds its maximum size.");
+ }
+
+ const double next_bucket_count =
+ std::ceil(double(m_mod) * REHASH_SIZE_MULTIPLICATION_FACTOR);
+ if (!std::isnormal(next_bucket_count)) {
+ TSL_RH_THROW_OR_TERMINATE(std::length_error,
+ "The hash table exceeds its maximum size.");
+ }
+
+ if (next_bucket_count > double(max_bucket_count())) {
+ return max_bucket_count();
+ } else {
+ return std::size_t(next_bucket_count);
+ }
+ }
+
+ std::size_t max_bucket_count() const { return MAX_BUCKET_COUNT; }
+
+ void clear() noexcept { m_mod = 1; }
+
+ private:
+ static constexpr double REHASH_SIZE_MULTIPLICATION_FACTOR =
+ 1.0 * GrowthFactor::num / GrowthFactor::den;
+ static const std::size_t MAX_BUCKET_COUNT =
+ std::size_t(double(std::numeric_limits::max() /
+ REHASH_SIZE_MULTIPLICATION_FACTOR));
+
+ static_assert(REHASH_SIZE_MULTIPLICATION_FACTOR >= 1.1,
+ "Growth factor should be >= 1.1.");
+
+ std::size_t m_mod;
+};
+
+namespace detail {
+
+#if SIZE_MAX >= ULLONG_MAX
+#define TSL_RH_NB_PRIMES 51
+#elif SIZE_MAX >= ULONG_MAX
+#define TSL_RH_NB_PRIMES 40
+#else
+#define TSL_RH_NB_PRIMES 23
+#endif
+
+static constexpr const std::array PRIMES = {{
+ 1u,
+ 5u,
+ 17u,
+ 29u,
+ 37u,
+ 53u,
+ 67u,
+ 79u,
+ 97u,
+ 131u,
+ 193u,
+ 257u,
+ 389u,
+ 521u,
+ 769u,
+ 1031u,
+ 1543u,
+ 2053u,
+ 3079u,
+ 6151u,
+ 12289u,
+ 24593u,
+ 49157u,
+#if SIZE_MAX >= ULONG_MAX
+ 98317ul,
+ 196613ul,
+ 393241ul,
+ 786433ul,
+ 1572869ul,
+ 3145739ul,
+ 6291469ul,
+ 12582917ul,
+ 25165843ul,
+ 50331653ul,
+ 100663319ul,
+ 201326611ul,
+ 402653189ul,
+ 805306457ul,
+ 1610612741ul,
+ 3221225473ul,
+ 4294967291ul,
+#endif
+#if SIZE_MAX >= ULLONG_MAX
+ 6442450939ull,
+ 12884901893ull,
+ 25769803751ull,
+ 51539607551ull,
+ 103079215111ull,
+ 206158430209ull,
+ 412316860441ull,
+ 824633720831ull,
+ 1649267441651ull,
+ 3298534883309ull,
+ 6597069766657ull,
+#endif
+}};
+
+template
+static constexpr std::size_t mod(std::size_t hash) {
+ return hash % PRIMES[IPrime];
+}
+
+// MOD_PRIME[iprime](hash) returns hash % PRIMES[iprime]. This table allows for
+// faster modulo as the compiler can optimize the modulo code better with a
+// constant known at the compilation.
+static constexpr const std::array
+ MOD_PRIME = {{
+ &mod<0>, &mod<1>, &mod<2>, &mod<3>, &mod<4>, &mod<5>,
+ &mod<6>, &mod<7>, &mod<8>, &mod<9>, &mod<10>, &mod<11>,
+ &mod<12>, &mod<13>, &mod<14>, &mod<15>, &mod<16>, &mod<17>,
+ &mod<18>, &mod<19>, &mod<20>, &mod<21>, &mod<22>,
+#if SIZE_MAX >= ULONG_MAX
+ &mod<23>, &mod<24>, &mod<25>, &mod<26>, &mod<27>, &mod<28>,
+ &mod<29>, &mod<30>, &mod<31>, &mod<32>, &mod<33>, &mod<34>,
+ &mod<35>, &mod<36>, &mod<37>, &mod<38>, &mod<39>,
+#endif
+#if SIZE_MAX >= ULLONG_MAX
+ &mod<40>, &mod<41>, &mod<42>, &mod<43>, &mod<44>, &mod<45>,
+ &mod<46>, &mod<47>, &mod<48>, &mod<49>, &mod<50>,
+#endif
+ }};
+
+} // namespace detail
+
+/**
+ * Grow the hash table by using prime numbers as bucket count. Slower than
+ * tsl::rh::power_of_two_growth_policy in general but will probably distribute
+ * the values around better in the buckets with a poor hash function.
+ *
+ * To allow the compiler to optimize the modulo operation, a lookup table is
+ * used with constant primes numbers.
+ *
+ * With a switch the code would look like:
+ * \code
+ * switch(iprime) { // iprime is the current prime of the hash table
+ * case 0: hash % 5ul;
+ * break;
+ * case 1: hash % 17ul;
+ * break;
+ * case 2: hash % 29ul;
+ * break;
+ * ...
+ * }
+ * \endcode
+ *
+ * Due to the constant variable in the modulo the compiler is able to optimize
+ * the operation by a series of multiplications, substractions and shifts.
+ *
+ * The 'hash % 5' could become something like 'hash - (hash * 0xCCCCCCCD) >> 34)
+ * * 5' in a 64 bits environment.
+ */
+class prime_growth_policy {
+ public:
+ explicit prime_growth_policy(std::size_t& min_bucket_count_in_out) {
+ auto it_prime = std::lower_bound(
+ detail::PRIMES.begin(), detail::PRIMES.end(), min_bucket_count_in_out);
+ if (it_prime == detail::PRIMES.end()) {
+ TSL_RH_THROW_OR_TERMINATE(std::length_error,
+ "The hash table exceeds its maximum size.");
+ }
+
+ m_iprime = static_cast(
+ std::distance(detail::PRIMES.begin(), it_prime));
+ if (min_bucket_count_in_out > 0) {
+ min_bucket_count_in_out = *it_prime;
+ } else {
+ min_bucket_count_in_out = 0;
+ }
+ }
+
+ std::size_t bucket_for_hash(std::size_t hash) const noexcept {
+ return detail::MOD_PRIME[m_iprime](hash);
+ }
+
+ std::size_t next_bucket_count() const {
+ if (m_iprime + 1 >= detail::PRIMES.size()) {
+ TSL_RH_THROW_OR_TERMINATE(std::length_error,
+ "The hash table exceeds its maximum size.");
+ }
+
+ return detail::PRIMES[m_iprime + 1];
+ }
+
+ std::size_t max_bucket_count() const { return detail::PRIMES.back(); }
+
+ void clear() noexcept { m_iprime = 0; }
+
+ private:
+ unsigned int m_iprime;
+
+ static_assert(std::numeric_limits::max() >=
+ detail::PRIMES.size(),
+ "The type of m_iprime is not big enough.");
+};
+
+} // namespace rh
+} // namespace tsl
+
+#endif
diff --git a/compiler/native/nerdcore/src/tsl/robin_hash.h b/compiler/native/nerdcore/src/tsl/robin_hash.h
new file mode 100644
index 000000000..89c7c96f2
--- /dev/null
+++ b/compiler/native/nerdcore/src/tsl/robin_hash.h
@@ -0,0 +1,1639 @@
+/**
+ * MIT License
+ *
+ * Copyright (c) 2017 Thibaut Goetghebuer-Planchon
+ *
+ * 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.
+ */
+#ifndef TSL_ROBIN_HASH_H
+#define TSL_ROBIN_HASH_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "robin_growth_policy.h"
+
+namespace tsl {
+
+namespace detail_robin_hash {
+
+template
+struct make_void {
+ using type = void;
+};
+
+template
+struct has_is_transparent : std::false_type {};
+
+template
+struct has_is_transparent::type>
+ : std::true_type {};
+
+template
+struct is_power_of_two_policy : std::false_type {};
+
+template
+struct is_power_of_two_policy>
+ : std::true_type {};
+
+// Only available in C++17, we need to be compatible with C++11
+template
+const T& clamp(const T& v, const T& lo, const T& hi) {
+ return std::min(hi, std::max(lo, v));
+}
+
+template
+static T numeric_cast(U value,
+ const char* error_message = "numeric_cast() failed.") {
+ T ret = static_cast(value);
+ if (static_cast(ret) != value) {
+ TSL_RH_THROW_OR_TERMINATE(std::runtime_error, error_message);
+ }
+
+ const bool is_same_signedness =
+ (std::is_unsigned::value && std::is_unsigned::value) ||
+ (std::is_signed::value && std::is_signed::value);
+ if (!is_same_signedness && (ret < T{}) != (value < U{})) {
+ TSL_RH_THROW_OR_TERMINATE(std::runtime_error, error_message);
+ }
+
+ return ret;
+}
+
+template
+static T deserialize_value(Deserializer& deserializer) {
+ // MSVC < 2017 is not conformant, circumvent the problem by removing the
+ // template keyword
+#if defined(_MSC_VER) && _MSC_VER < 1910
+ return deserializer.Deserializer::operator()();
+#else
+ return deserializer.Deserializer::template operator()();
+#endif
+}
+
+/**
+ * Fixed size type used to represent size_type values on serialization. Need to
+ * be big enough to represent a std::size_t on 32 and 64 bits platforms, and
+ * must be the same size on both platforms.
+ */
+using slz_size_type = std::uint64_t;
+static_assert(std::numeric_limits::max() >=
+ std::numeric_limits::max(),
+ "slz_size_type must be >= std::size_t");
+
+using truncated_hash_type = std::uint32_t;
+
+/**
+ * Helper class that stores a truncated hash if StoreHash is true and nothing
+ * otherwise.
+ */
+template
+class bucket_entry_hash {
+ public:
+ bool bucket_hash_equal(std::size_t /*hash*/) const noexcept { return true; }
+
+ truncated_hash_type truncated_hash() const noexcept { return 0; }
+
+ protected:
+ void set_hash(truncated_hash_type /*hash*/) noexcept {}
+};
+
+template <>
+class bucket_entry_hash {
+ public:
+ bool bucket_hash_equal(std::size_t hash) const noexcept {
+ return m_hash == truncated_hash_type(hash);
+ }
+
+ truncated_hash_type truncated_hash() const noexcept { return m_hash; }
+
+ protected:
+ void set_hash(truncated_hash_type hash) noexcept {
+ m_hash = truncated_hash_type(hash);
+ }
+
+ private:
+ truncated_hash_type m_hash;
+};
+
+/**
+ * Each bucket entry has:
+ * - A value of type `ValueType`.
+ * - An integer to store how far the value of the bucket, if any, is from its
+ * ideal bucket (ex: if the current bucket 5 has the value 'foo' and
+ * `hash('foo') % nb_buckets` == 3, `dist_from_ideal_bucket()` will return 2 as
+ * the current value of the bucket is two buckets away from its ideal bucket) If
+ * there is no value in the bucket (i.e. `empty()` is true)
+ * `dist_from_ideal_bucket()` will be < 0.
+ * - A marker which tells us if the bucket is the last bucket of the bucket
+ * array (useful for the iterator of the hash table).
+ * - If `StoreHash` is true, 32 bits of the hash of the value, if any, are also
+ * stored in the bucket. If the size of the hash is more than 32 bits, it is
+ * truncated. We don't store the full hash as storing the hash is a potential
+ * opportunity to use the unused space due to the alignment of the bucket_entry
+ * structure. We can thus potentially store the hash without any extra space
+ * (which would not be possible with 64 bits of the hash).
+ */
+template
+class bucket_entry : public bucket_entry_hash {
+ using bucket_hash = bucket_entry_hash;
+
+ public:
+ using value_type = ValueType;
+ using distance_type = std::int16_t;
+
+ bucket_entry() noexcept
+ : bucket_hash(),
+ m_dist_from_ideal_bucket(EMPTY_MARKER_DIST_FROM_IDEAL_BUCKET),
+ m_last_bucket(false) {
+ tsl_rh_assert(empty());
+ }
+
+ bucket_entry(bool last_bucket) noexcept
+ : bucket_hash(),
+ m_dist_from_ideal_bucket(EMPTY_MARKER_DIST_FROM_IDEAL_BUCKET),
+ m_last_bucket(last_bucket) {
+ tsl_rh_assert(empty());
+ }
+
+ bucket_entry(const bucket_entry& other) noexcept(
+ std::is_nothrow_copy_constructible::value)
+ : bucket_hash(other),
+ m_dist_from_ideal_bucket(EMPTY_MARKER_DIST_FROM_IDEAL_BUCKET),
+ m_last_bucket(other.m_last_bucket) {
+ if (!other.empty()) {
+ ::new (static_cast(std::addressof(m_value)))
+ value_type(other.value());
+ m_dist_from_ideal_bucket = other.m_dist_from_ideal_bucket;
+ }
+ tsl_rh_assert(empty() == other.empty());
+ }
+
+ /**
+ * Never really used, but still necessary as we must call resize on an empty
+ * `std::vector`. and we need to support move-only types. See
+ * robin_hash constructor for details.
+ */
+ bucket_entry(bucket_entry&& other) noexcept(
+ std::is_nothrow_move_constructible::value)
+ : bucket_hash(std::move(other)),
+ m_dist_from_ideal_bucket(EMPTY_MARKER_DIST_FROM_IDEAL_BUCKET),
+ m_last_bucket(other.m_last_bucket) {
+ if (!other.empty()) {
+ ::new (static_cast(std::addressof(m_value)))
+ value_type(std::move(other.value()));
+ m_dist_from_ideal_bucket = other.m_dist_from_ideal_bucket;
+ }
+ tsl_rh_assert(empty() == other.empty());
+ }
+
+ bucket_entry& operator=(const bucket_entry& other) noexcept(
+ std::is_nothrow_copy_constructible::value) {
+ if (this != &other) {
+ clear();
+
+ bucket_hash::operator=(other);
+ if (!other.empty()) {
+ ::new (static_cast(std::addressof(m_value)))
+ value_type(other.value());
+ }
+
+ m_dist_from_ideal_bucket = other.m_dist_from_ideal_bucket;
+ m_last_bucket = other.m_last_bucket;
+ }
+
+ return *this;
+ }
+
+ bucket_entry& operator=(bucket_entry&&) = delete;
+
+ ~bucket_entry() noexcept { clear(); }
+
+ void clear() noexcept {
+ if (!empty()) {
+ destroy_value();
+ m_dist_from_ideal_bucket = EMPTY_MARKER_DIST_FROM_IDEAL_BUCKET;
+ }
+ }
+
+ bool empty() const noexcept {
+ return m_dist_from_ideal_bucket == EMPTY_MARKER_DIST_FROM_IDEAL_BUCKET;
+ }
+
+ value_type& value() noexcept {
+ tsl_rh_assert(!empty());
+#if defined(__cplusplus) && __cplusplus >= 201703L
+ return *std::launder(
+ reinterpret_cast(std::addressof(m_value)));
+#else
+ return *reinterpret_cast(std::addressof(m_value));
+#endif
+ }
+
+ const value_type& value() const noexcept {
+ tsl_rh_assert(!empty());
+#if defined(__cplusplus) && __cplusplus >= 201703L
+ return *std::launder(
+ reinterpret_cast(std::addressof(m_value)));
+#else
+ return *reinterpret_cast(std::addressof(m_value));
+#endif
+ }
+
+ distance_type dist_from_ideal_bucket() const noexcept {
+ return m_dist_from_ideal_bucket;
+ }
+
+ bool last_bucket() const noexcept { return m_last_bucket; }
+
+ void set_as_last_bucket() noexcept { m_last_bucket = true; }
+
+ template
+ void set_value_of_empty_bucket(distance_type dist_from_ideal_bucket,
+ truncated_hash_type hash,
+ Args&&... value_type_args) {
+ tsl_rh_assert(dist_from_ideal_bucket >= 0);
+ tsl_rh_assert(empty());
+
+ ::new (static_cast(std::addressof(m_value)))
+ value_type(std::forward(value_type_args)...);
+ this->set_hash(hash);
+ m_dist_from_ideal_bucket = dist_from_ideal_bucket;
+
+ tsl_rh_assert(!empty());
+ }
+
+ void swap_with_value_in_bucket(distance_type& dist_from_ideal_bucket,
+ truncated_hash_type& hash, value_type& value) {
+ tsl_rh_assert(!empty());
+ tsl_rh_assert(dist_from_ideal_bucket > m_dist_from_ideal_bucket);
+
+ using std::swap;
+ swap(value, this->value());
+ swap(dist_from_ideal_bucket, m_dist_from_ideal_bucket);
+
+ if (StoreHash) {
+ const truncated_hash_type tmp_hash = this->truncated_hash();
+ this->set_hash(hash);
+ hash = tmp_hash;
+ } else {
+ // Avoid warning of unused variable if StoreHash is false
+ TSL_RH_UNUSED(hash);
+ }
+ }
+
+ static truncated_hash_type truncate_hash(std::size_t hash) noexcept {
+ return truncated_hash_type(hash);
+ }
+
+ private:
+ void destroy_value() noexcept {
+ tsl_rh_assert(!empty());
+ value().~value_type();
+ }
+
+ public:
+ static const distance_type EMPTY_MARKER_DIST_FROM_IDEAL_BUCKET = -1;
+ static const distance_type DIST_FROM_IDEAL_BUCKET_LIMIT = 4096;
+ static_assert(DIST_FROM_IDEAL_BUCKET_LIMIT <=
+ std::numeric_limits::max() - 1,
+ "DIST_FROM_IDEAL_BUCKET_LIMIT must be <= "
+ "std::numeric_limits::max() - 1.");
+
+ private:
+ using storage = typename std::aligned_storage::type;
+
+ distance_type m_dist_from_ideal_bucket;
+ bool m_last_bucket;
+ storage m_value;
+};
+
+/**
+ * Internal common class used by `robin_map` and `robin_set`.
+ *
+ * ValueType is what will be stored by `robin_hash` (usually `std::pair`
+ * for map and `Key` for set).
+ *
+ * `KeySelect` should be a `FunctionObject` which takes a `ValueType` in
+ * parameter and returns a reference to the key.
+ *
+ * `ValueSelect` should be a `FunctionObject` which takes a `ValueType` in
+ * parameter and returns a reference to the value. `ValueSelect` should be void
+ * if there is no value (in a set for example).
+ *
+ * The strong exception guarantee only holds if the expression
+ * `std::is_nothrow_swappable::value &&
+ * std::is_nothrow_move_constructible::value` is true.
+ *
+ * Behaviour is undefined if the destructor of `ValueType` throws.
+ */
+template
+class robin_hash : private Hash, private KeyEqual, private GrowthPolicy {
+ private:
+ template
+ using has_mapped_type =
+ typename std::integral_constant::value>;
+
+ static_assert(
+ noexcept(std::declval().bucket_for_hash(std::size_t(0))),
+ "GrowthPolicy::bucket_for_hash must be noexcept.");
+ static_assert(noexcept(std::declval().clear()),
+ "GrowthPolicy::clear must be noexcept.");
+
+ public:
+ template
+ class robin_iterator;
+
+ using key_type = typename KeySelect::key_type;
+ using value_type = ValueType;
+ using size_type = std::size_t;
+ using difference_type = std::ptrdiff_t;
+ using hasher = Hash;
+ using key_equal = KeyEqual;
+ using allocator_type = Allocator;
+ using reference = value_type&;
+ using const_reference = const value_type&;
+ using pointer = value_type*;
+ using const_pointer = const value_type*;
+ using iterator = robin_iterator;
+ using const_iterator = robin_iterator;
+
+ private:
+ /**
+ * Either store the hash because we are asked by the `StoreHash` template
+ * parameter or store the hash because it doesn't cost us anything in size and
+ * can be used to speed up rehash.
+ */
+ static constexpr bool STORE_HASH =
+ StoreHash ||
+ ((sizeof(tsl::detail_robin_hash::bucket_entry) ==
+ sizeof(tsl::detail_robin_hash::bucket_entry)) &&
+ (sizeof(std::size_t) == sizeof(truncated_hash_type) ||
+ is_power_of_two_policy::value) &&
+ // Don't store the hash for primitive types with default hash.
+ (!std::is_arithmetic::value ||
+ !std::is_same>::value));
+
+ /**
+ * Only use the stored hash on lookup if we are explicitly asked. We are not
+ * sure how slow the KeyEqual operation is. An extra comparison may slow
+ * things down with a fast KeyEqual.
+ */
+ static constexpr bool USE_STORED_HASH_ON_LOOKUP = StoreHash;
+
+ /**
+ * We can only use the hash on rehash if the size of the hash type is the same
+ * as the stored one or if we use a power of two modulo. In the case of the
+ * power of two modulo, we just mask the least significant bytes, we just have
+ * to check that the truncated_hash_type didn't truncated more bytes.
+ */
+ static bool USE_STORED_HASH_ON_REHASH(size_type bucket_count) {
+ if (STORE_HASH && sizeof(std::size_t) == sizeof(truncated_hash_type)) {
+ TSL_RH_UNUSED(bucket_count);
+ return true;
+ } else if (STORE_HASH && is_power_of_two_policy::value) {
+ return bucket_count == 0 ||
+ (bucket_count - 1) <=
+ std::numeric_limits::max();
+ } else {
+ TSL_RH_UNUSED(bucket_count);
+ return false;
+ }
+ }
+
+ using bucket_entry =
+ tsl::detail_robin_hash::bucket_entry;
+ using distance_type = typename bucket_entry::distance_type;
+
+ using buckets_allocator = typename std::allocator_traits<
+ allocator_type>::template rebind_alloc;
+ using buckets_container_type = std::vector;
+
+ public:
+ /**
+ * The 'operator*()' and 'operator->()' methods return a const reference and
+ * const pointer respectively to the stored value type.
+ *
+ * In case of a map, to get a mutable reference to the value associated to a
+ * key (the '.second' in the stored pair), you have to call 'value()'.
+ *
+ * The main reason for this is that if we returned a `std::pair&`
+ * instead of a `const std::pair&`, the user may modify the key which
+ * will put the map in a undefined state.
+ */
+ template
+ class robin_iterator {
+ friend class robin_hash;
+
+ private:
+ using bucket_entry_ptr =
+ typename std::conditional::type;
+
+ robin_iterator(bucket_entry_ptr bucket) noexcept : m_bucket(bucket) {}
+
+ public:
+ using iterator_category = std::forward_iterator_tag;
+ using value_type = const typename robin_hash::value_type;
+ using difference_type = std::ptrdiff_t;
+ using reference = value_type&;
+ using pointer = value_type*;
+
+ robin_iterator() noexcept {}
+
+ // Copy constructor from iterator to const_iterator.
+ template ::type* = nullptr>
+ robin_iterator(const robin_iterator& other) noexcept
+ : m_bucket(other.m_bucket) {}
+
+ robin_iterator(const robin_iterator& other) = default;
+ robin_iterator(robin_iterator&& other) = default;
+ robin_iterator& operator=(const robin_iterator& other) = default;
+ robin_iterator& operator=(robin_iterator&& other) = default;
+
+ const typename robin_hash::key_type& key() const {
+ return KeySelect()(m_bucket->value());
+ }
+
+ template ::value &&
+ IsConst>::type* = nullptr>
+ const typename U::value_type& value() const {
+ return U()(m_bucket->value());
+ }
+
+ template ::value &&
+ !IsConst>::type* = nullptr>
+ typename U::value_type& value() const {
+ return U()(m_bucket->value());
+ }
+
+ reference operator*() const { return m_bucket->value(); }
+
+ pointer operator->() const { return std::addressof(m_bucket->value()); }
+
+ robin_iterator& operator++() {
+ while (true) {
+ if (m_bucket->last_bucket()) {
+ ++m_bucket;
+ return *this;
+ }
+
+ ++m_bucket;
+ if (!m_bucket->empty()) {
+ return *this;
+ }
+ }
+ }
+
+ robin_iterator operator++(int) {
+ robin_iterator tmp(*this);
+ ++*this;
+
+ return tmp;
+ }
+
+ friend bool operator==(const robin_iterator& lhs,
+ const robin_iterator& rhs) {
+ return lhs.m_bucket == rhs.m_bucket;
+ }
+
+ friend bool operator!=(const robin_iterator& lhs,
+ const robin_iterator& rhs) {
+ return !(lhs == rhs);
+ }
+
+ private:
+ bucket_entry_ptr m_bucket;
+ };
+
+ public:
+#if defined(__cplusplus) && __cplusplus >= 201402L
+ robin_hash(size_type bucket_count, const Hash& hash, const KeyEqual& equal,
+ const Allocator& alloc,
+ float min_load_factor = DEFAULT_MIN_LOAD_FACTOR,
+ float max_load_factor = DEFAULT_MAX_LOAD_FACTOR)
+ : Hash(hash),
+ KeyEqual(equal),
+ GrowthPolicy(bucket_count),
+ m_buckets_data(bucket_count, alloc),
+ m_buckets(m_buckets_data.empty() ? static_empty_bucket_ptr()
+ : m_buckets_data.data()),
+ m_bucket_count(bucket_count),
+ m_nb_elements(0),
+ m_grow_on_next_insert(false),
+ m_try_shrink_on_next_insert(false) {
+ if (bucket_count > max_bucket_count()) {
+ TSL_RH_THROW_OR_TERMINATE(std::length_error,
+ "The map exceeds its maximum bucket count.");
+ }
+
+ if (m_bucket_count > 0) {
+ tsl_rh_assert(!m_buckets_data.empty());
+ m_buckets_data.back().set_as_last_bucket();
+ }
+
+ this->min_load_factor(min_load_factor);
+ this->max_load_factor(max_load_factor);
+ }
+#else
+ /**
+ * C++11 doesn't support the creation of a std::vector with a custom allocator
+ * and 'count' default-inserted elements. The needed contructor `explicit
+ * vector(size_type count, const Allocator& alloc = Allocator());` is only
+ * available in C++14 and later. We thus must resize after using the
+ * `vector(const Allocator& alloc)` constructor.
+ *
+ * We can't use `vector(size_type count, const T& value, const Allocator&
+ * alloc)` as it requires the value T to be copyable.
+ */
+ robin_hash(size_type bucket_count, const Hash& hash, const KeyEqual& equal,
+ const Allocator& alloc,
+ float min_load_factor = DEFAULT_MIN_LOAD_FACTOR,
+ float max_load_factor = DEFAULT_MAX_LOAD_FACTOR)
+ : Hash(hash),
+ KeyEqual(equal),
+ GrowthPolicy(bucket_count),
+ m_buckets_data(alloc),
+ m_buckets(static_empty_bucket_ptr()),
+ m_bucket_count(bucket_count),
+ m_nb_elements(0),
+ m_grow_on_next_insert(false),
+ m_try_shrink_on_next_insert(false) {
+ if (bucket_count > max_bucket_count()) {
+ TSL_RH_THROW_OR_TERMINATE(std::length_error,
+ "The map exceeds its maximum bucket count.");
+ }
+
+ if (m_bucket_count > 0) {
+ m_buckets_data.resize(m_bucket_count);
+ m_buckets = m_buckets_data.data();
+
+ tsl_rh_assert(!m_buckets_data.empty());
+ m_buckets_data.back().set_as_last_bucket();
+ }
+
+ this->min_load_factor(min_load_factor);
+ this->max_load_factor(max_load_factor);
+ }
+#endif
+
+ robin_hash(const robin_hash& other)
+ : Hash(other),
+ KeyEqual(other),
+ GrowthPolicy(other),
+ m_buckets_data(other.m_buckets_data),
+ m_buckets(m_buckets_data.empty() ? static_empty_bucket_ptr()
+ : m_buckets_data.data()),
+ m_bucket_count(other.m_bucket_count),
+ m_nb_elements(other.m_nb_elements),
+ m_load_threshold(other.m_load_threshold),
+ m_min_load_factor(other.m_min_load_factor),
+ m_max_load_factor(other.m_max_load_factor),
+ m_grow_on_next_insert(other.m_grow_on_next_insert),
+ m_try_shrink_on_next_insert(other.m_try_shrink_on_next_insert) {}
+
+ robin_hash(robin_hash&& other) noexcept(
+ std::is_nothrow_move_constructible<
+ Hash>::value&& std::is_nothrow_move_constructible::value&&
+ std::is_nothrow_move_constructible::value&&
+ std::is_nothrow_move_constructible::value)
+ : Hash(std::move(static_cast(other))),
+ KeyEqual(std::move(static_cast(other))),
+ GrowthPolicy(std::move(static_cast(other))),
+ m_buckets_data(std::move(other.m_buckets_data)),
+ m_buckets(m_buckets_data.empty() ? static_empty_bucket_ptr()
+ : m_buckets_data.data()),
+ m_bucket_count(other.m_bucket_count),
+ m_nb_elements(other.m_nb_elements),
+ m_load_threshold(other.m_load_threshold),
+ m_min_load_factor(other.m_min_load_factor),
+ m_max_load_factor(other.m_max_load_factor),
+ m_grow_on_next_insert(other.m_grow_on_next_insert),
+ m_try_shrink_on_next_insert(other.m_try_shrink_on_next_insert) {
+ other.clear_and_shrink();
+ }
+
+ robin_hash& operator=(const robin_hash& other) {
+ if (&other != this) {
+ Hash::operator=(other);
+ KeyEqual::operator=(other);
+ GrowthPolicy::operator=(other);
+
+ m_buckets_data = other.m_buckets_data;
+ m_buckets = m_buckets_data.empty() ? static_empty_bucket_ptr()
+ : m_buckets_data.data();
+ m_bucket_count = other.m_bucket_count;
+ m_nb_elements = other.m_nb_elements;
+
+ m_load_threshold = other.m_load_threshold;
+ m_min_load_factor = other.m_min_load_factor;
+ m_max_load_factor = other.m_max_load_factor;
+
+ m_grow_on_next_insert = other.m_grow_on_next_insert;
+ m_try_shrink_on_next_insert = other.m_try_shrink_on_next_insert;
+ }
+
+ return *this;
+ }
+
+ robin_hash& operator=(robin_hash&& other) {
+ other.swap(*this);
+ other.clear_and_shrink();
+
+ return *this;
+ }
+
+ allocator_type get_allocator() const {
+ return m_buckets_data.get_allocator();
+ }
+
+ /*
+ * Iterators
+ */
+ iterator begin() noexcept {
+ std::size_t i = 0;
+ while (i < m_bucket_count && m_buckets[i].empty()) {
+ i++;
+ }
+
+ return iterator(m_buckets + i);
+ }
+
+ const_iterator begin() const noexcept { return cbegin(); }
+
+ const_iterator cbegin() const noexcept {
+ std::size_t i = 0;
+ while (i < m_bucket_count && m_buckets[i].empty()) {
+ i++;
+ }
+
+ return const_iterator(m_buckets + i);
+ }
+
+ iterator end() noexcept { return iterator(m_buckets + m_bucket_count); }
+
+ const_iterator end() const noexcept { return cend(); }
+
+ const_iterator cend() const noexcept {
+ return const_iterator(m_buckets + m_bucket_count);
+ }
+
+ /*
+ * Capacity
+ */
+ bool empty() const noexcept { return m_nb_elements == 0; }
+
+ size_type size() const noexcept { return m_nb_elements; }
+
+ size_type max_size() const noexcept { return m_buckets_data.max_size(); }
+
+ /*
+ * Modifiers
+ */
+ void clear() noexcept {
+ if (m_min_load_factor > 0.0f) {
+ clear_and_shrink();
+ } else {
+ for (auto& bucket : m_buckets_data) {
+ bucket.clear();
+ }
+
+ m_nb_elements = 0;
+ m_grow_on_next_insert = false;
+ }
+ }
+
+ template
+ std::pair