From e1764d2cda4113f15a889d51432bd28f36ee67a5 Mon Sep 17 00:00:00 2001 From: Micah Havens Date: Thu, 3 Dec 2020 00:16:17 -0500 Subject: [PATCH] Lots of proofreading for grammar and spelling --- docs/pages/differences.md | 2 +- docs/pages/documentation.md | 12 +- docs/pages/draft.md | 6 +- docs/pages/faq.md | 174 ++++++------ docs/pages/installing.md | 72 ++--- docs/pages/libraries.md | 22 +- docs/pages/manual.md | 58 ++-- docs/pages/overview.md | 530 ++++++++++++++++++------------------ docs/pages/tutorial.md | 54 ++-- 9 files changed, 464 insertions(+), 466 deletions(-) diff --git a/docs/pages/differences.md b/docs/pages/differences.md index af62cd73..cb653ba0 100644 --- a/docs/pages/differences.md +++ b/docs/pages/differences.md @@ -7,7 +7,7 @@ toc: true order: 6 --- -Nelua had to reimplement all Lua libraries. Due to this some functions are not implemented or can't be implemented. This page explains availability of Lua functions in Nelua. +Nelua reimplements every Lua library. Due to this, some functions are not implemented or can't be implemented. This page shows the availability of Lua functions in Nelua. Implemented - ✔ diff --git a/docs/pages/documentation.md b/docs/pages/documentation.md index 4374c4d1..9ab7dc8b 100644 --- a/docs/pages/documentation.md +++ b/docs/pages/documentation.md @@ -15,13 +15,13 @@ Read this page after installing the Nelua compiler. ### [Overview](/overview/) -Overview features of Nelua, -the **most interesting page** to learn more about all the features and syntax. +Overview of Nelua's features, +the **most interesting page** to learn about the syntax and all of the features. ### [Manual](/manual/) Technical specification of Nelua, this page is more technical -thus can be dense to read, for a quick understanding of Nelua see the overview first. +and thus can be dense to read. For a quick understanding of Nelua, first read the overview. ### [Libraries](/libraries/) @@ -29,9 +29,9 @@ List of built-in libraries in Nelua and their contents. ### [Differences](/diffs/) -Direct comparison of Lua and Nelua standard libraries. +Direct comparison between the standard libraries of Lua and Nelua. ### [FAQ](/faq/) -Answers to frequently asked questions about Nelua, -look on this page for answers to doubts, or try the search bar. \ No newline at end of file +Answers to frequently asked questions about Nelua. +Look on this page for answers to doubts, or try the search bar. \ No newline at end of file diff --git a/docs/pages/draft.md b/docs/pages/draft.md index a339864d..3d2df894 100644 --- a/docs/pages/draft.md +++ b/docs/pages/draft.md @@ -8,13 +8,13 @@ order: 8 {% raw %} -This is a draft for features that are not implemented yet. Once a feature here is completed -its text will be moved into the overview page. +This is a draft for features that are not implemented yet. Once a feature here is completed, +its associated text will be moved into the overview page. {: .lead} Don't expect any of the examples here **to work or be implemented** in the future exactly as presented here, -these are mostly ideias. +these are mostly ideas. {: .callout.callout-warning} ## Iterated For diff --git a/docs/pages/faq.md b/docs/pages/faq.md index 5b021112..ddbd278a 100644 --- a/docs/pages/faq.md +++ b/docs/pages/faq.md @@ -10,113 +10,113 @@ order: 7 Answers to frequently asked questions about Nelua. {: .lead} -**Is your question not here?** Use the search bar to search in the documentation -or ask in the [discord chat](https://discord.gg/7aaGeG7), common questions asked -there will be moved here. +**Is your question not here?** Use the search bar to search the documentation, +or ask it in the [Discord server](https://discord.gg/7aaGeG7). Commonly asked questions +from there will be moved here. {: .callout.callout-info} ## Why Nelua? -Nelua was created with the intent to have an efficient compiled language -with syntax and similar to Lua, it's one of the few programmable statically typed -languages that combines a powerful compile time meta programming capabilities to -make efficient code. Nelua is developed by a game developer to make -games with it. +Nelua was created with the intent to make an efficient compiled language +with syntax similar to Lua. It is one of the few programmable statically typed +languages that uses powerful compile-time metaprogramming capabilities to +generate efficient code. Nelua is developed by a game developer who uses it to +make games. -## What Nelua means? +## What does Nelua mean? Nelua stands for *Native Extensible Lua*. ## Where does Nelua come from? Nelua is designed, created and maintained by [edubart](https://github.com/edubart). -The ideia of the language has been in the back of his mind during multiple years -working with games with Lua and C++. Then in 2019 it born and raised on GitHub +The idea of the language was in the back of his mind over multiple years of +working with games in Lua and C++. Then, in 2019, it was born on GitHub as an open source project. ## How stable is Nelua? -Nelua is in alpha state, most of its syntax are well defined, -low level features that are found in C are implemented and +Nelua is in alpha state. Most of its syntax is well defined, +low level features that are found in C are implemented, and most of the Lua standard APIs are implemented. However -some notable features found in Lua like exceptions, tables, -runtime dynamic typing, closures and coroutines are not implemented yet. +some notable features found in Lua such as exceptions, tables, +runtime dynamic typing, closures, and coroutines are not implemented yet. ## How is Nelua licensed? -The Nelua compiler, its standard library and its dependencies are MIT licensed. +The Nelua compiler, its standard library, and its dependencies are MIT licensed. This means you can use any license for programs developed with Nelua. -## Why Nelua follows Lua syntax and semantics? +## Why does Nelua follow Lua syntax and semantics? -* Lua is minimal and simple, this means not many features need to be replicated in Nelua, -thus the language can remain minimal, easy to use, efficient and stable. -* Nelua was created to be mixed with Lua programs in mind, where one +* Lua is minimal and simple, so not many features need to be replicated in Nelua, +thus the language can remain minimal, easy to use, efficient, and stable. +* Nelua was created to be mixed with Lua programs, where one would use Nelua to make real-time efficient code and Lua for -runtime scripting and compile-time meta programming. -* Nelua compiler uses Lua at compile time to enable advanced meta programming, -by using Lua makes the syntax of the Lua preprocessor and Nelua very similar. +runtime scripting and compile-time metaprogramming. +* The Nelua compiler uses Lua at compile time to enable advanced metaprogramming. +Using Lua makes the syntax of the Lua preprocessor and Nelua very similar. * Nelua is being developed by a Lua lover who desires to have the same syntax and semantics between his system programming language and scripting language. -* Nelua compiler is written in Lua with the intent to be hackable, -making the language with similar syntax and semantics as the compiler code base -makes easier for users to hack the compiler or to meta program. - -## Why Nelua compiles to C first? - -* C still one of the most efficient programming languages, thus Nelua can be efficient as C. -* Any C compiler can be used, usually most platforms supports C, thus Nelua can run anywhere, including the web with the Emscripten compiler. -* C code can be reused if the user someday decides to move away from Nelua, he can just get the generated C code, that is very human readable and continue on using C/C++. -* The generated C code can be reused to make C libraries, thus a library made in Nelua could be bound in any other language because most other languages supports some form of importing C libraries. -* Great C tools are available out there, thus C tools can be used with Nelua, -like debuggers, profilers and static analyzers. -* C is easy to read, thus the user can read the C generated code to get better low level -understanding of his code. -* Makes easy to import or use C code without costs in Nelua. +* The Nelua compiler is written in Lua with the intent to be hackable. +Designing the language to have similar syntax and semantics to the compiler codebase +makes it easier for users to hack the compiler or to metaprogram. + +## Why does Nelua compile to C first? + +* C still one of the most efficient programming languages, thus Nelua can be as efficient as C. +* Any C compiler can be used. Most platforms support C, thus Nelua can run anywhere, including the web (with the Emscripten compiler). +* The generated C code can be reused if the user someday decides to move away from Nelua. The user can just take the generated C code, since it is very human readable, and can continue using C/C++. +* The generated C code can be reused to make C libraries, thus a library made in Nelua could be bound in any other language, because most other languages support some form of importing C libraries. +* Great C tools are available which can be used with Nelua, +such as debuggers, profilers, and static analyzers. +* C is easy to read, thus the user can read the C generated code to get a better low-level +understanding of the code. +* It makes it easy to import or use C code without costs in Nelua. * C is simple to use and this makes the Nelua compiler simpler. -## Why Nelua does not use LLVM? +## Why does Nelua not use LLVM? -* By using LLVM Nelua would have a huge dependency and this would go against of one of its goals of being simple to compile and use. -* Being locked to LLVM would take out other great compilers that can perform better -in different situations than LLVM, like GCC can be more efficient in some cases. -* LLVM can be slow to compile huge projects, by using C the user can use for example the TCC compiler when developing to compile huge projects in a few milliseconds while LLVM would take minutes. -* LLVM generated code is not readable by most users, by using C the user -can read the generated code and have a low level understanding of his code. +* By using LLVM, Nelua would have a huge dependency. This would go against one of its goals of being simple to compile and use. +* Being locked to LLVM would remove the option of using other great compilers that can perform better +in certain situations, such as GCC. +* LLVM can be slow to compile huge projects. By using C the user can, for example, use the TCC compiler when developing in order to compile huge projects in just a few milliseconds. LLVM would take minutes. +* LLVM generated code is not readable to most users. By using C the user +can read the generated code and have a low level understanding of the code. -## Why Nelua have a garbage collector? +## Why does Nelua have a garbage collector? -Because it tries to replicate Lua features and semantics which for some things requires -a garbage collector, however Nelua has additional constructs to work -with manual memory management and the garbage collector can be completely disabled. -But when doing this the programming style is slightly different. Also -the Nelua author believes that garbage collection is good for rapid prototyping +Because it tries to replicate Lua features and semantics. Some of these things require +a garbage collector. However, Nelua has additional constructs to work +with manual memory management, and the garbage collector can be completely disabled if needed. +When doing this, the programming style is slightly different. +The Nelua author believes that garbage collection is good for rapid prototyping and for newcomers, and that manual memory management can be enabled later -when seeking performance or when the user becomes more experienced to manage the -memory on his own. +when seeking performance, or when the user becomes experienced enough to manage the +memory manually. -## Is Nelua interpreted or uses an interpreter? +## Does Nelua use an interpreter? -No, Nelua uses ahead of time compilation to create efficient native applications, -it doesn't do any kind of interpreting or JIT at runtime, this means it +No. Nelua uses ahead-of-time compilation to create efficient native applications. +It doesn't do any kind of interpreting or JIT at runtime, which means it can't parse or execute code generated at runtime. If you are looking -for something that could do this then consider LuaJIT which is an outstanding -JIT implementation for Lua or Ravi that is another JIT implementation -for Lua that supports type notations. However Nelua uses a Lua -interpreter at compile time for meta programming in its preprocessor. +for something that can do this, then consider LuaJIT, which is an outstanding +JIT implementation for Lua, or Ravi, which is another JIT implementation +for Lua that supports type notations. However, Nelua does use a Lua +interpreter at compile time for metaprogramming in its preprocessor. -## What kind of application is Nelua good for? +## What kinds of applications is Nelua good for? -Nelua is being created with the intent to be used in real-time applications -that requires efficiency and predictable performance such as games, game engines, -libraries or almost anything were one would use C. +Nelua is being developed with the intent to be used in real-time applications +that require efficiency and predictable performance, such as games, game engines, +libraries or almost any situation where one would normally use C. ## What have been the major influences in Nelua design? -Obviously Lua and C, then modern languages that tends to be a "better C", -like Nim, Odin, Zig. +Lua and C, as well as some modern languages that try to be a "better C," +like Nim, Odin, and Zig. -## How can I have syntax highlighting for Nelua code? +## How can I have syntax highlighting for my Nelua code? Nelua has syntax highlight plugins for the following editors: @@ -124,41 +124,41 @@ Nelua has syntax highlight plugins for the following editors: * [Visual Studio Code](https://github.com/edubart/nelua-vscode) * [Text Adept](https://github.com/Andre-LA/ta-nelua-mirror) -If you use other editor and make a plugin for Nelua share with the community. +If you use another editor and make a plugin for Nelua, please share it with the community. ## How can I debug my application? You can get backtraces of crashes by having GDB debugger installed -and running in debug mode with the `--debug` command line argument, -when doing this Nelua will run your application through GDB -and print out readable backtraces for your code. For more advanced debugging -you could use any C debugger manually. +and running in debug mode with the `--debug` command line argument. +When doing this Nelua will run your application through GDB +and print out readable backtraces for your code. For more advanced debugging, +you can use any C debugger manually. -## How to make my code more efficient? +## How do I make my code more efficient? -Nelua compiles by default with optimizations disabled and runtime checks enabled. +Nelua compiles with optimizations disabled and runtime checks enabled by default. To compile with optimization enabled and runtime checks disabled you must use the -`--release -P nochecks` command line argument. Also Nelua uses the a conservative -garbage collector by default, which can be heavy depending on use case, -users seeking performance and predictable runtimes should switch to +`--release -P nochecks` command line argument. Nelua also uses a conservative +garbage collector by default, which can be heavy depending on use case. +Users seeking performance and predictable runtimes should switch to manual memory management and disable the garbage collector with `-P nogc`. -If wanting even more performance you could pass more aggresive -compilation flags to your C compiler like `--cflags="-O3 -march=native -fno-plt -flto"`. +If you want even more performance you can pass more aggresive +compilation flags to your C compiler, for example: `--cflags="-O3 -march=native -fno-plt -flto"`. -## Where can I report mistake and issues? +## Where can I report mistakes and issues? -You can report issues about Nelua and its documentation in the -[github issues](https://github.com/edubart/nelua-lang/issues) page. +You can report issues about Nelua and its documentation at the +[GitHub issues](https://github.com/edubart/nelua-lang/issues) page. ## How can I support Nelua? -In many ways, giving a star on github, using Nelua and sharing +In many ways. Giving a star on GitHub, using Nelua and sharing your experience with others, reporting bugs, spreading it to the world, sharing projects made with it, making a blog post about it, -helping improving the documentation and tutorials, +helping to improve the documentation and tutorials, or through a [donation](https://patreon.com/edubart). -## Where can I discuss about Nelua? +## Where can I discuss Nelua? -Nelua developers and users generally discuss in the [discord chat](https://discord.gg/7aaGeG7). -There is also the [reddit community ](https://www.reddit.com/r/nelua/) although is inactive yet. +Nelua developers and users generally discuss in the [Discord server](https://discord.gg/7aaGeG7). +There is also a [Reddit community ](https://www.reddit.com/r/nelua/), although is inactive at the moment. diff --git a/docs/pages/installing.md b/docs/pages/installing.md index aa365f85..a5ec3542 100644 --- a/docs/pages/installing.md +++ b/docs/pages/installing.md @@ -13,17 +13,17 @@ Instructions for installing Nelua on Windows or Linux. To install Nelua you need a system with the following: -* Git (for cloning Nelua). -* A C compiler (GCC or Clang are recommended). -* Build tools (such as make). -* GDB debugger (in case you want to debug runtime errors). +* Git (for cloning Nelua) +* A C compiler (GCC or Clang are recommended) +* Build tools (such as make) +* GDB debugger (in case you want to debug runtime errors) ## Installing on Linux -Use your system package manager to install all the required tools first, -then clone, compile the dependencies and install using make. +Use your system's package manager to install all of the required tools first, +then clone, compile the dependencies, and install using make. -For example in Ubuntu: +For example, in Ubuntu: ```bash sudo apt-get install build-essential git gcc gdb @@ -31,36 +31,36 @@ git clone https://github.com/edubart/nelua-lang.git && cd nelua-lang sudo make install ``` -This will install in `/usr/local` by default, -you can install somewhere else using the `PREFIX` argument, -for example suppose you want to install in your home -then use `sudo make install PREFIX=~/nelua` -and Nelua compiler will be available at `~/nelua/bin/nelua`. +This will install to `/usr/local` by default. +You can install somewhere else using the `PREFIX` argument. +For example, suppose you want to install in your home directory. +Then you would use `sudo make install PREFIX=~/nelua`, +and the Nelua compiler would be available at `~/nelua/bin/nelua`. -Alternatively you can just run the `nelua.sh` file to run directly if you do not wish -to install anywhere on your system. +Alternatively you can run the `nelua.sh` file to run Nelua directly if you do not wish +to install it anywhere on your system. Proceed to the [testing section](#testing). ## Installing on Windows -MSYS2 is the recommended and supported environment to use Nelua on Windows, -although you could use other tools MSYS2 makes using Nelua very easy on Windows, -plus there are many useful C packages on MSYS2 that you could use install with ease like +MSYS2 is the recommended and supported environment to use Nelua on Windows. +Although you could use other tools, MSYS2 makes using Nelua very easy on Windows, +plus there are many useful C packages on MSYS2 that you can install with ease, such as SDL2. Download and install [MSYS2](https://www.msys2.org/). After installing open the **64 bit terminal**, that is, -**msys64** and update: +**msys64**, and update: ```bash pacman -Syu ``` -You may need open again the terminal and update a second time using the same command. +You may need close and reopen the terminal and update a second time using the same command. Now install all the required tools first, -then clone, compile the dependencies and install using make. +then clone, compile the dependencies, and install using make. ```bash pacman -S base-devel git mingw-w64-x86_64-toolchain gdb @@ -68,16 +68,16 @@ git clone https://github.com/edubart/nelua-lang.git && cd nelua-lang make install ``` -Proceed to the testing section. +Proceed to the [testing section](#testing). ## Installing with LuaRocks If you already have a [LuaRocks](https://luarocks.org/) -installation you could install Nelua with it. -Although this is not recommended, -because it won't use the bundled Lua's interpreter from Nelua, -thus you will have worse compile speeds and if your system does not have Lua 5.3+ yet -it won't work. Also trying this on Windows is not recommend +installation, you can install Nelua with it. +However, this is not recommended, +because it will not use the Lua interpreter bundled with Nelua, +so you will have worse compile speeds, and if your system does not have Lua 5.3+ +it will not work. Also, trying this on Windows is not recommend because getting LuaRocks to work there is troublesome. With a proper LuaRocks setup do: @@ -86,15 +86,15 @@ With a proper LuaRocks setup do: luarocks install https://raw.githubusercontent.com/edubart/nelua-lang/master/rockspecs/nelua-dev-1.rockspec ``` -After installing Nelua should be available in the LuaRocks binary path ready to be run. +After installing, Nelua should be available in the LuaRocks binary path, ready to be run. -Proceed to the testing section. +Proceed to the [testing section](#testing). ## Testing -Nelua should be installed, run `nelua -h` in terminal check if its working. -If doesn't work your environment `PATH` variable is missing the `bin` folder to Nelua installation, -then fix it or find and execute the full path to the installed Nelua compiler to use it. +Nelua should be installed. Run `nelua -h` in your terminal to check if it is working. +If doesn't work, your environment `PATH` variable is missing the `bin` folder of the Nelua installation. +Add it or find and execute the full path to the installed Nelua compiler to use it. Run the hello world example: @@ -102,14 +102,14 @@ Run the hello world example: nelua examples/helloworld.nelua ``` -You can run any file in `examples` or `tests` directory, -play with them test or to learn how to code in Nelua. +You can run any file in the `examples` or `tests` directories, +play with them to test or to learn how to code in Nelua. -The most interesting examples perhaps are the graphical ones, +The most interesting examples are perhaps the graphical ones, such as `snakesdl.nelua` and `condots.nelua`. -To run Snake SDL game demo for example you will need SDL2 library installed, -install it using your system's package manager and run: +To run the Snake SDL game demo, for example, you will need to have the SDL2 library installed. +Install it using your system's package manager and run the example: ```bash # install SDL2 on MSYS2 diff --git a/docs/pages/libraries.md b/docs/pages/libraries.md index a5e21b26..ffc2e60b 100644 --- a/docs/pages/libraries.md +++ b/docs/pages/libraries.md @@ -10,15 +10,15 @@ order: 5 This is a list of built-in libraries in Nelua. {: .lead} -To use a library use `require 'libraryname'`{:.language-nelua}. +To use a library, use `require 'libraryname'`{:.language-nelua}. {: .callout.callout-info} -This page is under construction and very incomplete. +This page is under construction and is very incomplete. {: .callout.callout-info} ## arg -[Arg library](https://github.com/edubart/nelua-lang/blob/master/lib/arg.nelua) allows to use command line arguments from the entry point. +The [arg library](https://github.com/edubart/nelua-lang/blob/master/lib/arg.nelua) allows to use command line arguments from the entry point. | Variable Name | Description | |---------------|------| @@ -27,7 +27,7 @@ This page is under construction and very incomplete. ## basic -[Basic library](https://github.com/edubart/nelua-lang/blob/master/lib/basic.nelua) contains common functions. +The [basic library](https://github.com/edubart/nelua-lang/blob/master/lib/basic.nelua) contains common functions. | Variable Name | Description | |---------------|------| @@ -41,7 +41,7 @@ This page is under construction and very incomplete. ## iterators -[Iterators library](https://github.com/edubart/nelua-lang/blob/master/lib/iterators.nelua) contains iterator related functions. +The [iterators library](https://github.com/edubart/nelua-lang/blob/master/lib/iterators.nelua) contains iterator-related functions. | Variable Name | Description | |---------------|------| @@ -55,7 +55,7 @@ This page is under construction and very incomplete. ## filestream -[Filestream library](https://github.com/edubart/nelua-lang/blob/master/lib/filestream.nelua) contains filestream record, mainly used for [`io`](https://nelua.io/libraries/#io) library. +The [filestream library](https://github.com/edubart/nelua-lang/blob/master/lib/filestream.nelua) contains filestream records, mainly used for the [`io`](https://nelua.io/libraries/#io) library. | Variable Name | Description | |---------------|------| @@ -75,7 +75,7 @@ This page is under construction and very incomplete. ## io -[IO library](https://github.com/edubart/nelua-lang/blob/master/lib/io.nelua), copies Lua `io`{:.language-nelua} library. +The [IO library](https://github.com/edubart/nelua-lang/blob/master/lib/io.nelua) copies Lua's `io`{:.language-nelua} library. | Variable Name | Description | |---------------|------| @@ -98,7 +98,7 @@ This page is under construction and very incomplete. ## math -[Math library](https://github.com/edubart/nelua-lang/blob/master/lib/math.nelua), copies Lua `math`{:.language-nelua} library with extra functions. +The [math library](https://github.com/edubart/nelua-lang/blob/master/lib/math.nelua) copies Lua's `math`{:.language-nelua} library with extra functions. | Variable Name | Description | |---------------|------| @@ -168,7 +168,7 @@ This page is under construction and very incomplete. ## os -[OS library](https://github.com/edubart/nelua-lang/blob/master/lib/os.nelua) copies Lua `os`{:.language-nelua} library. +The [OS library](https://github.com/edubart/nelua-lang/blob/master/lib/os.nelua) copies Lua's `os`{:.language-nelua} library. | Variable Name | Description | |---------------|------| @@ -312,7 +312,7 @@ This page is under construction and very incomplete. ## traits -[Traits library](https://github.com/edubart/nelua-lang/blob/master/lib/traits.nelua) contains useful functions to get information about types at runtime. +The [traits library](https://github.com/edubart/nelua-lang/blob/master/lib/traits.nelua) contains useful functions to get information about types at runtime. | Variable Name | Description | |---------------|------| @@ -325,7 +325,7 @@ This page is under construction and very incomplete. ## vector -[Vector library](https://github.com/edubart/nelua-lang/blob/master/lib/vector.nelua), typically used as an efficient vector. +The [Vector library](https://github.com/edubart/nelua-lang/blob/master/lib/vector.nelua) is an efficient vector implementation. | Variable Name | Description | |---------------|------| diff --git a/docs/pages/manual.md b/docs/pages/manual.md index e2d80ae9..cdec0a9b 100644 --- a/docs/pages/manual.md +++ b/docs/pages/manual.md @@ -10,42 +10,40 @@ order: 4 Technical specification of the Nelua language. {: .lead} -This page is under construction and very incomplete. +This page is under construction and is very incomplete. {: .callout.callout-info} ## 1 - Introduction -Nelua is a minimal, simple, efficient, statically typed, compiled, meta programmable, -safe and extensible systems programming language with a [Lua](https://www.lua.org/about.html) flavor. +Nelua is a minimal, simple, efficient, statically typed, compiled, metaprogrammable, +safe, and extensible systems programming language with a [Lua](https://www.lua.org/about.html) flavor. -Nelua is designed for performance sensitive applications, +Nelua is designed for performance-sensitive applications, like real-time applications and game engines. It has syntax and semantics similar to Lua, -but is designed to be able to work with optional garbage collection, type notations -and free from an interpreter. +but it is designed to work with optional garbage collection and type notations +and is free of an interpreter. -Nelua uses ahead of time compilation to compile to optimized native binaries and -is meta programmable at compile-time using Lua, making possible to -specialize static code at compile-time with ease to create efficient applications. +Nelua uses ahead-of-time compilation to compile to optimized native binaries, and +is metaprogrammable at compile-time using Lua, making it possible to +specialize static code at compile-time with ease in order to create efficient applications. -Nelua has two choices for memory management, -it's the developer choice to use garbage collection or manual memory management -depending on his use case. -By default the garbage collection enabled, +Nelua has two choices for memory management. +It is the developer's choice whether to use garbage collection or manual memory management. +By default garbage collection is enabled to make the language more familiar and easy to use for users coming from Lua. -Nelua compiler is written in Lua, this makes Nelua extensible, -thus programmers may add new extensions to the language -at compile time using its Lua preprocessor, such as new grammars, AST definitions, -semantics, type checkers, code generation and behaviors to the compiler. +The Nelua compiler is written in Lua. This makes Nelua extensible. +Programmers may add new extensions to the language +at compile-time using the Lua preprocessor, such as new grammars, AST definitions, +semantics, type checkers, code generation, and other behaviors. -Nelua permits mixing two approaches when coding, -a more low-level approach using specific Nelua's idioms, -such as type notations, efficient data structures (records, static arrays), manual memory management and pointers, which makes the performance efficient as C. -Or a more high-level approach using Lua's idioms, such as tables, metatables and untyped variables, -which makes the compiler uses a runtime library to provide the dynamic functionality. +Nelua permits mixing two approaches when coding: +a more low-level approach using Nelua-specific idioms, e.g. type notations, records, static arrays, manual memory management, pointers, etc., which make the performance efficient as C, +or a more high-level approach using Lua's idioms, such as tables, metatables and untyped variables, +which makes the compiler use a runtime library to provide dynamic functionality. -Nelua compiles to C first then to the target native binary. +Nelua compiles to C first, then to the target native binary. Nelua stands for *Native Extensible Lua*. @@ -70,23 +68,23 @@ TODO ## 3 - The Language -This section describes the lexis, the syntax, and the semantics of Nelua. +This section describes the lexis, syntax, and semantics of Nelua. In other words, this section describes which tokens are valid, how they can be combined, and what their combinations mean. ### 3.1 - Lexical Conventions -Nelua like Lua is a free-form language. It ignores spaces and comments between lexical +Nelua, like Lua, is a free-form language. It ignores spaces and comments between lexical elements (tokens), except as delimiters between two tokens. -In source code, Nelua recognizes as spaces the standard ASCII whitespace characters space, +In source code, Nelua recognizes as spaces the standard ASCII whitespace characters: space, form feed, newline, carriage return, horizontal tab and vertical tab. Names (also called *identifiers*) in Nelua can be any string of Latin letters, UTF-8 unicode character, -digits and underscores, not beginning with a digit and not being a reserved word. +digits and underscores, as long as they do not begin with a digit and are not a reserved word. Identifiers are used to name symbols, variables, types, table fields and labels. -The following same *keywords* from Lua are reserved and cannot be used as names: +The following *keywords* from Lua are reserved and cannot be used as identifiers: ```nelua and break do else elseif end @@ -101,8 +99,8 @@ Plus the following *keywords*: case continue defer global switch ``` -Nelua is a case-sensitive language, -for example `and` is a reserved word, but `And` and `AND` are two different valid names. +Nelua is a case-sensitive language. +For example `and` is a reserved word, but `And` and `AND` are two different valid identifiers. As a convention, programs should avoid creating names that start with an underscore followed by uppercase letters (such as `_VERSION`). diff --git a/docs/pages/overview.md b/docs/pages/overview.md index 74cd11d2..f5df4f32 100644 --- a/docs/pages/overview.md +++ b/docs/pages/overview.md @@ -8,55 +8,55 @@ order: 3 {% raw %} -This is a quick overview of the language features that are currently implemented by examples. +This is a quick overview of the language features that are currently implemented by the examples. {: .lead} -All the features and examples presented here should work with the latest Nelua, for -features not implemented yet see the [draft](/draft/). +All of the features and examples presented here should work with the latest Nelua version. For +features not yet implemented see the [draft](/draft/). {: .callout.callout-info} ## A note for Lua users -Most of Nelua syntax and semantics -are similar to Lua, thus if you know Lua you probably know Nelua too. However Nelua have many -additions to code with type notations, to make more efficient code and to meta program. -This overview try to focus more on those features. +Most of Nelua's syntax and semantics +are similar to Lua, thus, if you know Lua, you probably know Nelua as well. However, Nelua has many +additions, such as code with type notations, to make code more efficient and to allow metaprogramming. +This overview will try to focus on those features. -There is no interpreter or VM, all the code is converted directly into native machine code, -thus expect better efficiency than Lua. However this means that Nelua can't load -code generated at runtime, the user is encouraged to generate code at compile-time +There is no interpreter or VM, all of the code is converted directly into native machine code, +so expect better efficiency than Lua. However, this means that Nelua **cannot load +code generated at runtime**, the user is encouraged to generate code at compile-time using the preprocessor. -Although copying Lua code with minor changes is a goal of Nelua, not all Lua -features are implemented yet. Mostly the dynamic part such as tables and handling dynamic types -at runtime is not implemented yet, thus at the moment is best to try Nelua using -records instead of tables and type notations in function definitions. +Although copying Lua syntax and semantics with minor changes is a goal of Nelua, not all Lua +features are implemented yet. Most of the dynamic parts such as tables and handling dynamic types +at runtime are not implemented yet, so at the moment, using +records instead of tables and type notations in function definitions are recommended. Visit [this](/diffs/) page for the full list of available features. {: .callout.callout-warning} ## A note for C users -Nelua tries to expose most of C features without overhead, thus expect -to get near C performance when coding in the C style, that is, using +Nelua tries to expose most of C's features without overhead, so expect +to get near C performance when coding in the C style; that is, using type notations, manual memory management, pointers and records (structs). -The semantics are not exactly as C semantics but close. There are slight differences -to minimize undefined behaviors (like initialize to zero by default) and -other ones to keep Lua semantics (like integer division rounds towards minus infinity). -However there are ways to get C semantics for each case when needed. +The semantics are not exactly the same as C semantics, but they are close. There are slight differences +to minimize undefined behaviors (like initializing to zero by default) and +others to maintain consistency with Lua semantics (like integer division rounding towards negative infinity). +However, there are ways to use C semantics when needed. -The preprocessor is much more powerful than C preprocessor, -because it's actually the compiler running in Lua, -thus you can interact with the compiler while parsing. The preprocessor should -be used for making generic code, code specialization and avoiding code duplication. +The preprocessor is much more powerful than C's preprocessor, +because it is actually the compiler running in Lua, +so you can interact with the compiler during parsing. The preprocessor should +be used for making generic code, code specialization, and avoiding code duplication. -Nelua generates everything compiled into a single readable C file, -if you know C is recommended to read the generated C code sometimes -to learn more what exactly the compiler outputs. +Nelua compiles everything into a single readable C file. +If you know C, it is recommended that you read the generated C code +to learn more about what exactly the compiler outputs. ## Hello world -Simple hello world program is just like in Lua: +A simple *hello world* program is just the same as in Lua: ```lua print 'Hello world!' @@ -64,7 +64,7 @@ print 'Hello world!' ## Comments -Comments are just like in Lua: +Comments are just like Lua: ```nelua -- one line comment @@ -80,8 +80,8 @@ Comments are just like in Lua: ## Variables -Variables are declared or defined like in Lua, but optionally -you can specify it's type when declaring: +Variables are declared or defined like in Lua, but you may optionally +specify a type when declaring: ```nelua local a = nil -- of deduced type 'any', initialized to nil @@ -92,8 +92,8 @@ local pi: number = 3.14 -- of type 'number', initialized to 1 print(a,b,s,one,pi) -- outputs: nil false test 1 3.1400000 ``` -The compiler takes advantages of types to make compile-time checks, runtime checks -and generate **efficient code** for that **specific type**. +The compiler takes advantage of types for compile-time and runtime checks +and to generate **efficient code** for the **specific type used**. {:.alert.alert-info} ### Type deduction @@ -109,15 +109,15 @@ print(a) -- outputs: 2 -- end of scope, compiler deduced 'a' to be of type 'integer' ``` -The compiler does it best it can to deduce the type for you, in most situations +The compiler does the best it can to deduce the type for you. In most situations it should work, but in some corner cases you may want to explicitly set a type for a variable. {:.alert.alert-info} ### Type collision -In case of different types being assigned to a same variable, -then the compiler deduces the variable type -to the `any` type, a type that can hold anything an runtime, this makes Nelua code compatible with lua values semantics: +In the case of different types being assigned to the same variable, +the compiler deduces the variable type +to be the `any` type, a type that can hold anything at runtime. This makes Nelua code compatible with Lua semantics: ```nelua local a -- a type will be deduced @@ -127,14 +127,14 @@ print(a) -- outputs: false -- a is deduced to be of type 'any', because it could hold an 'integer' or a 'boolean' ``` -The **any type is poorly supported** at the moment, so please at the moment **avoid this situation**, that is, avoid making the compiler deduce types collisions that would be deduced to the `any` type. Usually you don't want use any types anyway, as they are less efficient. Collision between different numeric types are fine, -the compiler always resolves to the largest appropriate number type. +**The any type is poorly supported** at the moment, so please **avoid this situation** for now, that is, avoid making the compiler deduce types collisions that would result in an `any` type. Usually, you don't want use any types anyway, as they are less efficient. Collision between different numeric types are fine, +as the compiler always resolves to the largest appropriate number type. {:.alert.alert-warning} ### Zero initialization -Variables declared but not defined early are always initialized to zeros by default, -this prevents undefined behaviors: +Variables declared but not defined early are always initialized to zeros by default. +This prevents undefined behaviors: ```nelua local a -- variable of deduced type 'any', initialized to 'nil' @@ -142,13 +142,13 @@ local i: integer -- variable of type 'integer', initialized to 0 print(a, i) --outputs: nil 0 ``` -Zero initialization can be **optionally disabled** using the `` [annotation](#annotations), -although not advised, usually one would do this only for micro optimization purposes. +Zero initialization can be **optionally disabled** using the `` [annotation](#annotations). +Although not advised, one could do this for micro optimization purposes. {:.alert.alert-info} ### Auto variables -Variables declared as `auto` have its type deduced early based only in the type of its first assignment: +A variable declared as `auto` has its type deduced early based only on the type of its first assignment: ```nelua local a: auto = 1 -- a is deduced to be of type 'integer' @@ -161,30 +161,30 @@ print(a) -- outputs: 1 ``` Auto variables were not intended to be used in variable declarations -like in the example above, because usually you can omit the type -and the compiler will automatically deduce already, -unless you want the compiler to deduce early. -The `auto` type was really created to be used with [polymorphic functions](#polymorphic-functions). +like in the example above, because in most cases you can omit the type +and the compiler will automatically deduce it. +This can be used, however, if you want the compiler to deduce early. +The `auto` type was mainly created to be used with [polymorphic functions](#polymorphic-functions). {:.alert.alert-warning} -### Compile time variables +### Compile-time variables -Comptime variables have its value known at compile-time: +Compile-time variables have their values known at compile-time: ```nelua local a = 1 + 2 -- constant variable of value '3' evaluated and known at compile-time ``` -The compiler takes advantages of compile-time variables to generate +The compiler takes advantage of compile-time variables to generate **efficient code**, because compile-time variables can be processed at compile-time. -Compile time variables are also useful -for using as compile-time parameters in [polymorphic functions](#polymorphic-functions). +Compile-time variables are also useful +as compile-time parameters in [polymorphic functions](#polymorphic-functions). {:.alert.alert-info} ### Const variables -Const variables can be assigned once at runtime however they cannot mutate: +Const variables can be assigned once at runtime, however, they cannot mutate: ```nelua local x = 1 @@ -196,15 +196,15 @@ print(a) -- outputs: 1 --a = 2 ``` -Const annotation can also be used for function arguments. +The const annotation can also be used for function arguments. The use of `` annotation is mostly for aesthetic -purposes, it's usage does not change efficiency. +purposes. Its usage does not affect efficiency. {:.alert.alert-info} ## Symbols -Symbols are named identifiers for functions, types or variables. +Symbols are named identifiers for functions, types, and variables. ### Local symbol @@ -223,7 +223,7 @@ end ### Global symbol -Global symbols are visible in other source files, they can only be declared in the top scope: +Global symbols are visible in other source files. They can only be declared in the top scope: ```nelua global global_a = 1 @@ -239,7 +239,7 @@ print(global_a) -- outputs: 1 print(global_f()) -- outputs: f ``` -Unlike Lua, to declare a global variable you **must explicitly** use the +Unlike Lua, to declare a global variable you **must explicitly use** the `global` keyword. {:.alert.alert-info} @@ -254,12 +254,12 @@ print(π) -- outputs 3.14 ## Control flow -Nelua provides the same control flow mechanism from Lua, plus some additional -ones to make low level coding easier, like `switch`, `defer` and `continue` statements. +Nelua provides the same control flow mechanisms as Lua, plus some additional +ones to make low level programming easier, like `switch`, `defer`, and `continue` statements. ### If -If statement is just like in Lua: +If statements work just like in Lua: ```nelua local a = 1 -- change this to 2 or 3 to trigger other ifs @@ -274,7 +274,7 @@ end ### Switch -Switch statement is similar to C switches: +The switch statement is similar to C: ```nelua local a = 1 -- change this to 2 or 3 to trigger other ifs @@ -289,12 +289,12 @@ end ``` The case expression can only contain **integral** numbers known at **compile-time**. The -compiler can generate more optimized code when using a switch instead of many ifs for integers. +compiler can generate more optimized code when using a switch instead of using many if statements for integers. {:.alert.alert-info} ### Do -Do blocks are useful to create arbitrary scopes to avoid collision of +Do blocks are useful for creating arbitrary scopes to avoid collision of variable names: ```nelua @@ -310,7 +310,7 @@ end ### Defer -Defer statement is useful for executing code at scope termination. +The defer statement is useful for executing code upon scope termination. ```nelua do @@ -324,12 +324,12 @@ end Defer is meant to be used for **releasing resources** in a deterministic manner **on scope termination**. The syntax and functionality is inspired by the similar statement in the Go language. -It's guaranteed to be executed in reverse order before any `return`, `break` or `continue` statement. +It is guaranteed to be executed in reverse order before any `return`, `break` or `continue` statement. {:.alert.alert-info} ### Goto -Gotos are useful to get out of nested loops and jump between codes: +Gotos are useful to get out of nested loops and jump between lines: ```nelua local haserr = true @@ -356,7 +356,7 @@ end ### Repeat -Repeat is also like in Lua: +Repeat also functions as in Lua: ```nelua local a = 0 @@ -367,13 +367,13 @@ repeat until stop ``` -Note that like Lua, a variable declared inside `repeat` scope **is visible** inside it's condition expression. +Note that, like Lua, a variable declared inside a `repeat` scope **is visible** inside its condition expression. {:.alert.alert-info} ### Numeric For -Numeric for are like in Lua, meaning they are inclusive for the first and the last -element: +Numeric for is like in Lua, meaning it is inclusive of the first and the last +elements: ```nelua for i = 0,5 do @@ -382,12 +382,12 @@ for i = 0,5 do end ``` -Like in Lua, numeric for loops always evaluate it's begin, end and step expressions **only once**. The iterate +Like in Lua, numeric for loops always evaluate the begin, end, and step expressions **just once**. The iterate variable type is automatically deduced using the begin and end expressions only. {:.alert.alert-info} #### Exclusive For -An exclusive for is available to do exclusive for loops, they work using +The exclusive for is available to create exclusive for loops. They work using comparison operators `~=` `<=` `>=` `<` `>`: ```nelua @@ -397,8 +397,8 @@ end ``` #### Stepped For -The last parameter in for syntax is the step, it's counter is always incremented -with `i = i + step`, by default step is always 1, when using negative steps reverse for is possible: +The last parameter in for syntax is the step. Its counter is always incremented +with `i = i + step`. By default the step is always 1. When using negative steps, a reverse for loop is possible: ```nelua for i=5,0,-1 do @@ -407,7 +407,7 @@ end ``` ### Continue -Continue statement is used to skip a loop to it's next iteration: +The continue statement is used to skip to the next iteration of a loop: ```nelua for i=1,10 do @@ -419,7 +419,7 @@ end ``` ### Break -Break statement is used to break a loop: +The break statement is used to immediately exit a loop: ```nelua for i=1,10 do @@ -432,7 +432,7 @@ end ## Primitive types -Primitives types are all the basic types builtin in the compiler. +Primitives types are the basic types built into the compiler. ### Boolean @@ -443,11 +443,11 @@ local c = true print(a,b,c) -- outputs: false false true ``` -The `boolean` is defined as `bool` in C code. +The `boolean` is defined as a `bool` in the generated C code. ### Numbers -Number literals are defined similar as in Lua: +Number literals are defined like in Lua: ```nelua local a = 1234 -- variable of type 'integer' @@ -469,7 +469,7 @@ local b = 1_f32 -- variable of type 'float32' print(a,b) --outputs: 1234 1.000000 ``` -The following table shows Nelua primitive numeric types and is related type in C: +The following table shows Nelua primitive numeric types and their related types in C: | Type | C Type | Suffixes | |-------------------|---------------------|---------------------| @@ -497,12 +497,12 @@ The following table shows Nelua primitive numeric types and is related type in C *\* Only supported by some C compilers and architectures.* {:.text-muted} -The types `isize` and `usize` types are usually 32 bits wide on 32-bit systems, +The types `isize` and `usize` are usually 32 bits wide on 32-bit systems, and 64 bits wide on 64-bit systems. When you need an integer value you **should use** `integer` unless you have a specific reason to use a sized or unsigned integer type. -The `integer`, `uinteger` and `number` **are intended to be configurable**, by default +The `integer`, `uinteger` and `number` **are intended to be configurable**. By default they are 64 bits for all architectures, but this can be customized by the user at compile-time via the preprocessor when needed. {:.alert.alert-info} @@ -510,8 +510,8 @@ via the preprocessor when needed. ### Strings There are two types of strings, the `string` used for strings allocated at runtime, -and `stringview` used for strings literals defined at compile-time and as views -of runtime strings too. +and `stringview` used for strings literals defined at compile-time as well as for views +of runtime strings. ```nelua -- to use the 'string' type we must import from the standard library @@ -524,21 +524,21 @@ local str3: stringview = 'stringview two' -- also a 'stringview' print(str1, str2, str3) -- outputs: "my string" "static stringview" "stringview two" ``` -The major difference of `stringview` and `string` is that `stringview` doesn't -manage the string memory, i.e. it doesn't allocates or deallocate strings. +The major difference between `stringview` and `string` is that `stringview` doesn't +manage the string memory, i.e. it doesn't allocate or deallocate strings. The `string` type is usually allocated at runtime and it frees the string memory -once it reference count reaches 0. When the garbage collector is disabled +once its reference count reaches 0. When the garbage collector is disabled, the `stringview` uses weak references, thus any `stringview` pointing to a `string` is invalidated once the related `string` is freed. Both types can be converted from one to another. -Like in Lua, `string` **is immutable**, this make the semantics similar to Lua. -If the programmer wants a mutable string he can always implement his own string class. +Like in Lua, `string` **is immutable**. This makes the semantics similar to Lua. +If the programmer wants a mutable string, implementing a custom string class is easily achievable. {:.alert.alert-info} ### Array -Array is a list with where its size is fixed and known at compile-time: +An array is a list with a size that is fixed and known at compile-time: ```nelua local a: array(integer, 4) = {1,2,3,4} @@ -550,9 +550,9 @@ local len = #b -- get the length of the array, should be 4 print(len) -- outputs: 4 ``` -When passing an array to a function as an argument, it is **passed by value**, -this means the array is copied and can incur in some performance overhead. -Thus when calling functions you mostly want to pass arrays by reference +When passing an array to a function as an argument, it is **passed by value**. +This means the array is copied. This can incur some performance overhead. +Thus when calling functions, you may want to pass arrays by reference using the [reference operator](#dereferencing-and-referencing) when appropriate. {:.alert.alert-warning} @@ -576,7 +576,7 @@ local a: Weeks = Weeks.Monday print(a) -- outputs: 1 ``` -The programmer must always initialize the first enum value, this choice +The programmer must always initialize the first enum value. This choice was made to makes the code more clear when reading. {:.alert.alert-info} @@ -591,19 +591,19 @@ a = false -- now holds the type 'boolean' at runtime print(a) -- outputs false ``` -The `any` type makes Nelua semantics compatible to Lua, you can use it to make untyped code -just like in Lua, however know that you pays the price in +The `any` type makes Nelua semantics compatible to Lua. You can use it to make untyped code +just like in Lua, however know that you pay the price in performance, as operations on `any` types generate lots of branches at runtime, -thus **less efficient code**. +meaning **less efficient code**. {:.alert.alert-info} -The **any type is poorly supported** at the moment, so please at the moment **avoid using it**. -Usually you don't want use any types anyway, as they require runtime branching, thus less efficient. +The **any type is poorly supported** at the moment, so please **avoid using it** for now. +Usually you don't want use any types anyway, as they require runtime branching, and are thus less efficient. {:.alert.alert-warning} ### Record -Record store variables in a block of memory: +Records store variables in a block of memory: ```nelua local Person = @record { @@ -630,7 +630,7 @@ d.age = 22 print(d.name, d.age) ``` -Records are straight translated to C structs. +Records are directly translated to C structs. {:.alert.alert-info} ### Pointer @@ -646,14 +646,14 @@ local i: pointer(integer) -- pointer to an integer local i: *integer ``` -Pointers are straight translated to C raw pointers. -Unlikely C pointer arithmetic is disallowed, -to do pointer arithmetic you must explicitly cast to and from integers. +Pointers are directly translated to C raw pointers. +Unlike C, pointer arithmetic is disallowed. +To do pointer arithmetic you must explicitly cast to and from integers. {:.alert.alert-info} #### Unbounded Array -An an array with size 0 is an unbounded array, +An array with size 0 is an unbounded array, that is, an array with unknown size at compile time: ```nelua @@ -665,19 +665,19 @@ a_ptr = &a -- takes the reference of 'a' print(a_ptr[1]) ``` -Unbounded array is useful to index pointers, because unlikely -C you cannot index pointers unless it's a pointer -of an unbounded array. +An unbounded array is useful for indexing pointers, because unlike +C, you cannot index a pointer unless it is a pointer +to an unbounded array. {:.alert.alert-info} Unbounded arrays are **unsafe**, because bounds checking is -not possible at compile-time or runtime, prefer the [span](#span) +not possible at compile time or runtime. Use the [span](#span) to have bounds checking. {:.alert.alert-warning} ### Function type -The function type, mostly used to store callbacks, is the type of a function: +The function type, mostly used to store callbacks, is a pointer to a function: ```nelua local function add_impl(x: integer, y: integer): integer @@ -695,13 +695,13 @@ add = double_add_impl print(add(1,2)) -- outputs 6 ``` -The function type is just a pointer, thus can be converted to/from generic pointers. +The function type is just a pointer, and thus can be converted to/from generic pointers. {:.alert.alert-info} ### Span Span, also known as "fat pointers" or "slices" in other languages, -are pointers to a block of contiguous elements which size is known at runtime: +are pointers to a block of contiguous elements of which the size is known at runtime: ```nelua require 'span' @@ -711,8 +711,8 @@ print(s[0], s[1]) -- outputs: 1 2 print(#s) -- outputs 4 ``` -The advantage of using a span instead of a pointer it that spans generates runtime -checks for out of bounds access, thus usually a code using a span is **more safe**. +The advantage of using a span instead of a pointer is that spans generate runtime +checks for out of bounds access, so oftentimes code using span is **safer**. The runtime checks can be disabled in release builds. {:.alert.alert-info} @@ -720,14 +720,14 @@ The runtime checks can be disabled in release builds. The niltype is the type of `nil`. -Niltype type is not useful by itself, it's only useful when using with unions to create the +The niltype is not useful by itself, it is only useful when using with unions to create the optional type or for detecting `nil` arguments in [polymorphic functions](#polymorphic-functions). {:.alert.alert-info} ### The "type" type The `type` type is the type of a symbol that refers to a type. -Symbols with this type is used at compile-time only, they are useful for aliasing types: +Symbols with this type are used at compile-time only. They are useful for aliasing types: ```nelua local MyInt: type = @integer -- a symbol of type 'type' holding the type 'integer' @@ -735,13 +735,13 @@ local a: MyInt -- variable of type 'MyInt' (actually an 'integer') print(a) -- outputs: 0 ``` -In the middle of statements the `@` token is required to precede a type expression, -this token signs the compiler that a type expression is expect after it. +In the middle of statements the `@` token is required to precede a type expression. +This token signals to the compiler that a type expression comes after it. {:.alert.alert-info} #### Size of a type -You can use the operator `#` to get a size in bytes of any type: +You can use the operator `#` to get the size of any type in bytes: ```nelua local Vec2 = @record{x: integer, y: integer} @@ -750,7 +750,7 @@ print(#Vec2) -- outputs: 8 ### Implicit type conversion -Some types can be implicit converted, for example any arithmetic type can be +Some types can be implicitly converted. For example, any arithmetic type can be converted to any other arithmetic type: ```nelua @@ -760,7 +760,7 @@ print(u) -- outputs: 1 ``` Implicit conversion generates **runtime checks** for **loss of precision** -in the conversion, if this happens the application crashes with a narrow casting error. +in the conversion. If this happens the application crashes with a narrow casting error. The runtime checks can be disabled in release builds. {:.alert.alert-warning} @@ -776,7 +776,7 @@ print(i, f) -- outputs: 1 1.000000 ``` If a type is aliased to a symbol then -is also possible to convert variables by calling the symbol: +it is possible to convert variables by calling the symbol: ```nelua local MyNumber = @number @@ -785,7 +785,7 @@ local f = MyNumber(i) -- convert 'i' to the type 'number' print(i, f) -- outputs: 1 1.000000 ``` -Unlikely implicit conversion, explicit conversions skip runtime checks: +Unlike implicit conversion, explicit conversions skip runtime checks: ```nelua local ni: integer = -1 @@ -842,7 +842,7 @@ All Lua operators are provided: | ref | `&a`{:.language-nelua} | memory reference | {: .table.table-bordered.table-striped.table-sm} -All the operators follows Lua semantics, i.e.: +All the operators follow Lua semantics, i.e.: * `/` and `^` promotes numbers to floats. * `//` and `%` rounds the quotient towards minus infinity. * `///` and `%%%` rounds the quotient towards zero. @@ -850,14 +850,14 @@ All the operators follows Lua semantics, i.e.: * Bitwise shifts are defined for negative and large shifts. * `and`, `or`, `not`, `==`, `~=` can be used on any variable type. -The additional operators over Lua are `>>>`, `///`, `%%%`, `$` and `&`, +The additional operators not found in Lua are `>>>`, `///`, `%%%`, `$` and `&`, used for low level programming. {:.alert.alert-info} ## Functions -Functions are declared like in Lua, -but arguments and returns can have the type explicitly specified: +Functions are declared as in Lua, +but arguments and returns can have their types explicitly specified: ```nelua local function add(a: integer, b: integer): integer @@ -892,18 +892,18 @@ print(get(1)) -- outputs: 1 In contrast with variable declaration, when the type is omitted from a function argument there is no -automatic deducing of the argument type, instead it's assumed the argument must -be of the `any` type, this makes Nelua semantics more compatible with Lua semantics. +automatic deducing of the argument type. Instead it is assumed the argument must +be of the `any` type. This makes Nelua semantics more compatible with Lua semantics. {:.alert.alert-info} -At the moment avoid doing this and you must **explicit set types for functions arguments**, -due to the poor support for `any` type yet. Omitting the type for the return type is fine, +Avoid doing this at the moment, and **explicitly set types for function arguments**, +due to the poor support for `any` type. Omitting the type for the return type is fine because the compiler can deduce it. {:.alert.alert-warning} ### Recursive calls -Functions can call itself recursively: +Functions can call themselves recursively: ```nelua local function fib(n: integer): integer @@ -913,13 +913,13 @@ end print(fib(10)) -- outputs: 55 ``` -Function that does recursive calls itself must **explicit set the return type**, +Function that do recursive calls must **explicitly set the return type**, i.e, the compiler cannot deduce the return type. {:.alert.alert-warning} ### Multiple returns -Functions can have multiple returns like in Lua: +Functions can have multiple return values as in Lua: ```nelua local function get_multiple() @@ -948,8 +948,8 @@ Multiple returns are efficient and packed into C structs in the code generator. ### Top scope closures -Functions declared in the top scope works as top scope closure, -they have access to all local variables declared before it: +Functions declared in the top scope work as top scope closures. +They have access to all local variables declared beforehand: ```nelua local counter = 1 -- 'a' lives in the heap because it's on the top scope @@ -962,20 +962,20 @@ increment() print(counter) -- outputs 2 ``` -Unlikely Lua, -when declaring functions in the top scope the compiler takes advantages of the fact that -top scope variables is always accessible in the program static storage memory +Unlike Lua, +when declaring functions in the top scope, the compiler takes advantage of the fact that +top scope variables are always accessible in the program's static storage memory to create lightweight closures without -needing to hold a upvalue reference or use a garbage collector, -thus they are very lightweight and does not incur costs like a closure nested in a function. +needing to hold an upvalue reference or to use a garbage collector. +Therefore they are very lightweight and do not incur costs like a closure nested in a function would. {:.alert.alert-info} ### Polymorphic functions -Polymorphic functions, or in short poly functions in the sources, -are functions which contains arguments that proprieties can -only be known when calling the function at compile-time. -They are defined and processed lately when calling it for the first time. +Polymorphic functions, or poly functions for short in the sources, +are functions which contain arguments whose proprieties can +only be known when calling the function at compile time. +They are defined and processed later when calling it for the first time. They are used to specialize the function for different arguments types: ```nelua @@ -992,7 +992,7 @@ print(b) -- outputs: 3.000000 ``` In the above, the `auto` type is used as a generic placeholder to replace the function argument -by the incoming call type, this makes possible to make a generic function for multiple types. +with the incoming call type. This makes it possible to create a generic function for multiple types. Polymorphic functions are memoized, that is, only defined once for each kind of specialization. {:.alert.alert-info} @@ -1002,8 +1002,8 @@ Later we will show how polymorphic functions are more useful when used in combin ### Record functions -A record type can have functions defined for it, this makes useful to -organize functions that are to be used just within the record: +A record type can have functions defined for it. This makes it possible to +create functions that are to be used only within the record: ```nelua local Vec2 = @record{x: number, y: number} @@ -1018,8 +1018,8 @@ print(v.x, v.y) -- outputs: 1 2 ### Record methods -A method is function defined for record that takes a reference to the record type -as its first argument, this first argument is visible as `self` inside the method. +A method is function defined for record that takes a reference to the record +as its first argument. This first argument is visible as `self` inside the method. For defining or calling a method the colon token `:` must be used, just like in Lua. ```nelua @@ -1049,9 +1049,9 @@ the object being called. ### Record metamethods -Some special methods using the `__` prefix are used by the compiler to defines behaviors -on certain operations with the record type, -they are called metamethods and are similar to the Lua metamethods: +Some special methods using the `__` prefix are used by the compiler to define behaviors +on certain operations with the record type. +They are called metamethods and are similar to Lua metamethods: ```nelua require 'math' @@ -1076,7 +1076,7 @@ local len = #c -- calls the __len metamethod print(len) -- outputs: 7.2 ``` -Complete list of the metamethods that can be defined for records: +Complete list of metamethods that can be defined for records: | Name | Syntax | Kind | Operation | |---|---|---|---| @@ -1112,7 +1112,7 @@ Complete list of the metamethods that can be defined for records: ### Record globals -Sometimes is useful to declare a global variable inside a record type, +Sometimes it is useful to declare a global variable inside a record type, using the record as a "namespace": ```nelua @@ -1128,7 +1128,7 @@ like tables are used to make modules in Lua. ### Calls with nested records -You can define and later initialize complex records structures in a Lua like style: +You can define and later initialize complex records structures in a Lua-like style: ```nelua local WindowConfig = @record{ @@ -1154,7 +1154,7 @@ create_window({title="hi", pos={x=1, y=2}}) ## Memory management By default Nelua uses a garbage collector to allocate and deallocate memory on its own. -However it can be disabled with the pragma `nogc` via the command line using `-P nogc` +However, it can be disabled with the pragma `nogc` via the command line using `-P nogc` or in the sources: ```nelua @@ -1169,22 +1169,22 @@ print(str) -- the string was destroyed and is now empty, outputs nothing ``` Notice that when disabling the garbage collector the coding style is -different from Lua usual style, because now you need to **think of each allocation -and deallocation**, including for strings, otherwise memory in your application will leak, -thus is best to leave the GC enabled when you need rapid prototyping. +different from the usual Lua style, since you now need to **think of each allocation +and deallocation**, including strings, otherwise memory in your application will leak. +Thus it is best to leave the GC enabled when you need rapid prototyping. {:.alert.alert-warning} Disable the GC if you want to control the memory on your own for performance reasons, -know how to deal with memory management and don't mind the additional cognitive load -when coding without automatic memory management. +if you know how to deal with memory management and don't mind the additional cognitive load +when coding. {:.alert.alert-info} ### Allocating memory with the GC -Nelua provides many allocators to assist managing memory. +Nelua provides many allocators to assist in managing memory. The most important ones are the `allocators.general` and `allocators.gc`. -When using the GC you should allocated using the `gc_allocator`: +When using the GC you should allocate using the `gc_allocator`: ```nelua require 'string' require 'memory' @@ -1206,8 +1206,8 @@ because it marks the allocated memory region for scanning for references. ### Allocating memory manually -For doing manual memory management you can use the general purpose allocator, -that is based on the system's `malloc` and `free` functions: +For doing manual memory management, you can use the general purpose allocator, +which is based on the system's `malloc` and `free` functions: ```nelua ## pragmas.nogc = true -- disables the GC @@ -1227,7 +1227,7 @@ p = nilptr ### Dereferencing and referencing -The operator `&` is used to get a reference a variable, +The operator `&` is used to get a reference to a variable, and the operator `$` is used to access the reference. ```nelua @@ -1241,7 +1241,7 @@ print($ap) -- outputs 3 ### Automatic referencing and dereferencing -The compiler can perform automatic referencing or dereferencing for records or arrays: +The compiler can perform automatic referencing or dereferencing for records and arrays: ```nelua local Person = @record{name: stringview, age: integer} @@ -1259,7 +1259,7 @@ local p_ref: *Person = &p local p_copy: Person = $p_ref ``` -The above example is not much useful by itself, +The above example is not very useful by itself, but permits auto referencing when doing method calls: ```nelua @@ -1275,21 +1275,21 @@ p:print_info() -- perform auto referencing of 'p' when calling here Person.print_info(p) -- equivalent, also performs auto referencing ``` -The automatic referencing and dereferencing mechanism allows to use -any unary operator, binary operator, function call or method call +The automatic referencing and dereferencing mechanism allows the use +of any unary operator, binary operator, function call, or method call by value or by reference, for records or arrays. {:.alert.alert-info} ## Meta programming -The language offers advanced features for meta programming by having a full Lua preprocessor -at compile-time that can generate and manipulate code when compiling. +The language offers advanced features for metaprogramming by having a full Lua preprocessor +at compile time that can generate and manipulate code when compiling. ### Preprocessor -At compile-time a Lua preprocessor is available to render arbitrary code, -it works similar to templates in the web development world because they emit -code between it's statements. +At compile time a Lua preprocessor is available to render arbitrary code. +It works similarly to templates in the web development world, because it emits +code written between its statements. Lines beginning with `##` and between `##[[ ]]` are Lua code evaluated by the preprocessor: @@ -1308,7 +1308,7 @@ if something then ##[[ end ]] ``` -For instance the above code compile exactly as: +For instance, the above code compiles exactly as: ```nelua local a = 0 @@ -1319,11 +1319,11 @@ a = a + 1 print(a) ``` -Using the lua preprocessor you can generate complex codes at compile-time. +Using the Lua preprocessor, you can generate complex code at compile-time. ### Emitting AST nodes (statements) -It's possible to manually emit AST node for statements while preprocessing: +It is possible to manually emit AST nodes for statements while preprocessing: ```nelua ##[[ @@ -1338,7 +1338,7 @@ end ## print_macro('hello') ``` -The above code compile exactly as: +The above code compiles exactly as: ```nelua print('hello') @@ -1347,19 +1347,19 @@ print('hello') For a complete list of AST shapes that can be created using the `aster` module read the [AST definitions file](https://github.com/edubart/nelua-lang/blob/master/nelua/astdefs.lua) or the [syntax definitions spec file](https://github.com/edubart/nelua-lang/blob/master/spec/02-syntaxdefs_spec.lua) -for many examples. +for examples. {:.alert.alert-info} ### Emitting AST nodes (expressions) -It's possible to manually emit AST node for expressions while preprocessing: +It is possible to manually emit AST nodes for expressions while preprocessing: ```nelua local a = #[aster.Number{'dec','1'}]# print(a) -- outputs: 1 ``` -The above code compile exactly as: +The above code compiles exactly as: ```nelua local a = 1 @@ -1377,7 +1377,7 @@ local mybool = #[false]# print(deg2rad, hello, mybool) -- outputs: 0.017453 helloworld false ``` -The above code compile exactly as: +The above code compiles exactly as: ```nelua local deg2rad = 0.017453292519943 @@ -1401,7 +1401,7 @@ local Weekends = @enum { Friday=0, Saturday, Sunday } print(Weekends.#|'S'..string.lower('UNDAY')|#) ``` -The above code compile exactly as: +The above code compiles exactly as: ```nelua local myvar = 1 @@ -1416,7 +1416,7 @@ print(Weekends.Sunday) ### Preprocessor templated macros -Macros can be created by declaring functions in the preprocessor with its body +A macros can be created by declaring a function in the preprocessor with its body containing normal code: ```nelua @@ -1441,10 +1441,10 @@ print(x) ### Preprocessor macros emitting AST nodes Creating macros using the template rendering mechanism -in the previously example is handy but have limitations +in the previous example is handy, but has limitations and is not flexible enough for all cases. For example, -suppose you want to create an arbitrary length array, in this -case you will need to manually emit AST node: +suppose you want to create an arbitrarily sized array. In this +case you will need to manually emit AST nodes: ```nelua ##[[ @@ -1476,7 +1476,7 @@ end local a = #[create_sequence(integer, 10)]# ``` -The above code compile exactly as: +The above code compiles exactly as: ```nelua local a = (@[10]integer){1,2,3,4,5,6,7,8,9,10} @@ -1484,7 +1484,7 @@ local a = (@[10]integer){1,2,3,4,5,6,7,8,9,10} ### Code blocks as arguments to preprocessor functions -Block of codes can be passed to macros by surrounding it inside a function: +Blocks of code can be passed to macros by surrounding them inside a function: ```nelua ##[[ @@ -1502,7 +1502,7 @@ local counter = 1 ## end) ``` -The above code compile exactly as: +The above code compiles exactly as: ```nelua local counter = 1 @@ -1518,7 +1518,7 @@ counter = counter + 1 ### Generic code via the preprocessor -Using macros its possible to create generic code: +Using macros it is possible to create generic code: ```nelua ## function Point(PointT, T) @@ -1550,7 +1550,7 @@ local Weekends = @enum { Friday=0, Saturday, Sunda } ## end ``` -The above code compile exactly as: +The above code compiles exactly as: ```nelua local Weekends = @enum { Friday=0, Saturday, Sunday } @@ -1568,7 +1568,7 @@ local p: Person = {name='Joe', age=21} print(p.age) -- outputs '21' ``` -The above code compile exactly as: +The above code compiles exactly as: ```nelua local Person = @record{name: string, age: integer} @@ -1576,13 +1576,13 @@ local p: Person = {name='Joe', age=21} print(p.age) -- outputs '21' ``` -The compiler is implemented and runs using Lua and the preprocess -is actually a lua function that the compiler is running, thus it's possible to even modify -or inject code to the compiler itself on the fly. +The compiler is implemented and runs using Lua, and the preprocessor +is actually a Lua function that the compiler is running, so it is even possible to modify +or inject code into the compiler itself on the fly. ### Preprocessing polymorphic functions -Polymorphic functions can be specialized at compile-time +Polymorphic functions can be specialized at compile time when used in combination with the preprocessor: ```nelua @@ -1617,10 +1617,10 @@ starts with `##[[` or `##[=[` (any number of `=` tokens you want between the brackets) and ends with `]]` or `]=]` (matching the number of `=` tokens previously used): ```nelua --- this is an preprocessor code block +-- this is a preprocessor code block ##[[ function my_compiletime_function(str) - print(str) -- print at compile-time + print(str) -- print at compile time end ]] @@ -1632,20 +1632,20 @@ As shown in the last line, functions defined inside of the preprocessor code blocks can be evaluated arbitrarily from any part of the code, at any point, using `##`. -Although said block was defined for a single module it will be available for all -modules required after them, because declarations default to the global scope in Lua. -If you'd like to avoid polluting other module's -preprocessor environments then declare its functions as `local`. +Although said block was defined for a single module, it will be available for all +modules required afterwards, because declarations default to the global scope in Lua. +If you would like to avoid polluting other module's +preprocessor environments, declare its functions as `local`. ### Preprocessor function modularity Suppose you want to use the same preprocessor function from multiple Nelua modules. As explained in the [preprocessor code blocks](#preprocessor-code-blocks) section, one idea is to -declare everything in that block as global, thus it would also be available in -preprocessor evaluation from other modules. +declare everything in that block as global so that everything would also be available in +the preprocessor evaluation of other modules. -For example, on `module_A.nelua`: +For example, in `module_A.nelua`: ```nelua ##[[ @@ -1656,7 +1656,7 @@ end ]] ``` -Then, on `module_B.nelua`: +Then, in `module_B.nelua`: ```nelua require 'module_A' @@ -1665,13 +1665,13 @@ require 'module_A' ``` Although this seems harmless, it can get messy if you define a function with -the same name on different modules. It also means you're relying on global +the same name in different modules. It also means you're relying on global scope semantics from the preprocessor, which might be unpredictable or brittle due to evaluation order. Fortunately, there's a more modular approach for code reuse which does not rely on global scope. Simply create a standalone Lua module and require it on all -Nelua modules you would want to use it. +Nelua modules where you want to use it. The previous example would be refactored as follows: @@ -1694,18 +1694,18 @@ return { bar = bar } ``` Aside from modularity, this has the benefit of your preprocessor code being -simply Lua code which can leverage all your editor's tooling and configuration, +simply Lua code which can leverage all of your editor's tooling and configuration, such as a code formatter, syntax highlighter, completions, etc. If the Lua module is not in the same directory where the compiler is running from, then `require` -will fail to find it, to solve this -you can set `LUA_PATH` system's environment variable to a pattern which matches that directory, -for example doing `export LUA_PATH="/myprojects/mymodules/?.lua"`{:.language-bash} in your terminal (notice the `?.lua` at the end). +will fail to find it. To solve this +you can set your system's `LUA_PATH` environment variable to a pattern which matches that directory, +for example, executing `export LUA_PATH="/myprojects/mymodules/?.lua"`{:.language-bash} in your terminal (notice the `?.lua` at the end). {:.alert.alert-info} ### Preprocessor utilities -The preprocessor comes with some pre-defined functions to assist meta programming. +The preprocessor comes with some pre-defined functions to assist metaprogramming. #### static_error @@ -1732,9 +1732,9 @@ Used to throw compile-time assertions: ## Generics A generic is a special type created using a preprocessor function -that is evaluated at compile-time to generate a specialized type based -on compile-time arguments, to do this the `generalize` macro is used. -It's hard to explain in words, lets view a full example: +that is evaluated at compile time to generate a specialized type based +on compile-time arguments. To do this the `generalize` macro is used. +It is hard to explain in words, so take a look at this full example: ```nelua -- Define a generic type for creating a specialized FixedStackArray @@ -1818,13 +1818,13 @@ do -- test with 'number' type end ``` -Generics are powerful to **specialize efficient code at compile-time** -based on different compile-time arguments, they are used in many places in the -standard library for example to create +Generics are powerful for **specializing efficient code at compile time** +based on different compile-time arguments. They are used in many places in the +standard library to, for example, create the [vector](https://github.com/edubart/nelua-lang/blob/master/lib/vector.nelua) [sequence](https://github.com/edubart/nelua-lang/blob/master/lib/sequence.nelua) and [span](https://github.com/edubart/nelua-lang/blob/master/lib/span.nelua) -classes. Generics is similar to C++ templates. +classes. Generics are similar to C++ templates. {:.alert.alert-info} Generics are **memoized**, that is, they are evaluated and defined just once for the @@ -1833,15 +1833,15 @@ same compile-time arguments. ## Concepts -Concepts is a powerful system used to specialize [polymorphic functions](#polymorphic-functions) +Concepts are a powerful system used to specialize [polymorphic functions](#polymorphic-functions) with efficiency at compile-time. An argument of a polymorphic function can use the special concept type defined by a -preprocessor function that when evaluated at compile-time -decides whether if the incoming variable type matches the concept requirements. +preprocessor function that, when evaluated at compile time, +decides whether the incoming variable type matches the concept requirements. -To create a concept use preprocessor function `concept`: +To create a concept, use the preprocessor function `concept`: ```nelua local an_arithmetic = #[concept(function(attr) @@ -1867,22 +1867,22 @@ print(add(1, 2)) -- outputs 3 -- add(1, true) ``` -When the concepts of a function is matched for the first time, -a specialized function is defined just for that incoming types, -thus the compiler generates different functions in C code for each different match, -this means that the code is specialized -for each type and handled efficiently because the code does -not need to do runtime type branching, the type branching is only done at compile-time. +When the concepts of a function are matched for the first time, +a specialized function is defined just for those incoming types, +thus the compiler generates different functions in C code for each different match. +This means that the code is specialized +for each type and is handled efficiently because the code does +not need to do runtime type branching (the type branching is only done at compile time). -The property `type.is_arithmetic` is used here to check the incoming type, -all the properties defined by the compiler to check the incoming types can be +The property `type.is_arithmetic` is used here to check the incoming type. +All the properties defined by the compiler to check the incoming types can be [seen here](https://github.com/edubart/nelua-lang/blob/master/nelua/types.lua#L44). {:.alert.alert-info} ### Specializing with concepts -A concept can match multiple types, thus is possible to specialize -further a polymorphic function using a concept: +A concept can match multiple types, thus it is possible to specialize +a polymorphic function further using a concept: ```nelua require 'string' @@ -1918,9 +1918,9 @@ i.e. specialized functions for different argument types are memoized. ### Specializing concepts for records -Sometimes you want to check weather a record matches a concept, -to do this you can set a field on its type to later check in the concept -plus you can also use in the preprocessor to assist specializing code: +Sometimes you may want to check whether a record matches a concept. +To do this you can set a field on its type to later check in the concept, +plus you can use it in the preprocessor to assist in specializing code: ```nelua local Vec2 = @record{x: number, y: number} @@ -1957,8 +1957,8 @@ print(v.x, v.y) -- outputs: 2 4 ### Concepts with logic -You can put some logic in your concept, to check for any kind of proprieties -that the incoming `attr` should satisfy, and return compile-time errors +You can put some logic in your concept to check for any kind of proprieties +that the incoming `attr` should satisfy, and to return compile-time errors explaining why the concept didn't match: ```nelua @@ -2021,7 +2021,7 @@ print(sum_container(&b)) -- outputs: 55 ### Concept that infers to another type Sometimes is useful to infer a concept to a different type -from the incoming `attr`, for example suppose you want to specialize a function +from the incoming `attr`. For example, suppose you want to specialize a function that optionally accepts any kind of arithmetic, but you really want it to be implemented as an number: @@ -2053,8 +2053,8 @@ print(get_number(2)) -- prints 2 ### Facultative concept -Facultative concept are common to use, thus there is -a shortcut for creating them, for instance this the previous code is equivalent to: +Facultative concepts are commonly used, thus there is +a shortcut for creating them. For instance, the previous code is equivalent to this: ```nelua local function get_number(x: facultative(number)) @@ -2075,7 +2075,7 @@ without any runtime costs. ### Overload concept Using concepts to overload functions for different incoming types -at compile-time is a common use, so there is also a shortcut for creating overload concepts: +at compile time is a common use, so there is also a shortcut for creating overload concepts: ```nelua local function foo(x: overload(integer,stringview,niltype)) @@ -2093,12 +2093,12 @@ foo('hello') -- outputs: got string hello foo(nil) -- outputs: got nothing ``` -Use this when you want to specialize different argument types at compile-time +Use this when you want to specialize different argument types at compile time without runtime costs. ## Annotations -Annotations are used to inform the compiler different behaviors in the code +Annotations are used to prompt the compiler to behave differently during code generation. ### Function annotations @@ -2151,14 +2151,14 @@ int nelua_main() { } ``` -Notice that the `puts` functions is **declared automatically**, +Notice that the `puts` function is **declared automatically**, i.e., there is no need to include the header that declares the function. {:.alert.alert-info} ### Importing C functions declared in headers Sometimes you need to import a C function that is declared -in a C header, specially if its declared as a macro: +in a C header, specially if it is declared as a macro: ```nelua -- `nodecl` is used because this function doesn't need to be declared by Nelua, @@ -2189,7 +2189,7 @@ that is declared in a C header, otherwise the function will have duplicate decla ### Including C files with defines -Sometimes you need to include a C file but defining something before the include: +Sometimes you need to include a C file while defining something before the include: ```nelua -- link SDL2 library @@ -2212,8 +2212,8 @@ SDL_Quit() ### Importing C functions using a different name -The `` annotation uses the same name of its symbol name, -but it's possible import using a different name: +The `` annotation uses the same name as its symbol name, +but it is possible to import the function under a different name: ```nelua -- we pass the C function name as a parameter for `cimport` @@ -2243,7 +2243,7 @@ we could, but we let Nelua declare the function. ### Passing C flags -It's possible to add custom C flags when compiling via the preprocessor: +It is possible to add custom C flags when compiling via the preprocessor: ```nelua ##[[ @@ -2261,7 +2261,7 @@ the C compiler will compile with the cflags `-Ofast` otherwise `-Og`. ### Emitting raw C code -Sometimes to do low level stuff in C, or skip Nelua default semantics, +Sometimes to do low level things in C, or to avoid Nelua's default semantics, you may want to emit raw C code: ```nelua @@ -2281,14 +2281,14 @@ do_stuff() Nelua can emit C code in 3 different sections, in the global **declarations** section using `cemitdecl`, in the global **definitions** section using `cemitdef` -or the **current scope** section using `cemit`. Usually you +or the **current scope** section using `cemit`. Usually, you want to use `cemit`. {:.alert.alert-info} ### Exporting named C functions -You can use Nelua to create C libraries, when doing this +You can use Nelua to create C libraries. When doing this, you may want to fix the name of the generated C function and export it: ```nelua @@ -2312,7 +2312,7 @@ int64_t mylib_foo() { ### C primitives -For importing C functions, additional compatibility primitive types are provided: +For importing C functions, additional primitive types are provided for compatibility: | Type | C Type | Suffixes | |-------------------|----------------------|------------------| @@ -2333,15 +2333,15 @@ For importing C functions, additional compatibility primitive types are provided | `cstring` | `char*` | `_cstring` | {: .table.table-bordered.table-striped.table-sm} -Use this types for **importing C functions only**, for doing usual -code prefer the other Nelua primitive types. +Use these types for **importing C functions only**. For normal +code, use the other Nelua primitive types. {:.alert.alert-info} {% endraw %} -*[closure]: Closure are functions that captures variables from its parent scope. -*[upvalue]: A variable captured from in a scope above the closure. -*[integral]: A whole number, numbers that has not fractional part. +*[closure]: Closures are functions that capture variables from their parent scopes. +*[upvalue]: A variable captured from inside a scope above the closure. +*[integral]: A whole number, a number that has no fractional part. *[GC]: Garbage Collector Libraries >> diff --git a/docs/pages/tutorial.md b/docs/pages/tutorial.md index 31e7595c..e6c3daa9 100644 --- a/docs/pages/tutorial.md +++ b/docs/pages/tutorial.md @@ -12,18 +12,18 @@ This is a basic tutorial for the Nelua Programming Language, for running your first application. {: .lead} -**Don't have Nelua installed yet?** Then read the [installing tutorial](/installing/) first. +**Don't have Nelua installed yet?** Read the [installing tutorial](/installing/) first. {: .callout.callout-info} ## Your first program -You can basically code like you would code in Lua, for example the hello world program: +You can code in Nelua much like you would code in Lua. For example, a hello world program is written much like in Lua: ```nelua print 'Hello world' ``` -This example is already in the repository as an example, first clone the language repository +This example is already in the repository as an example. First clone the language repository if you haven't yet: ```bash @@ -31,12 +31,12 @@ git clone git@github.com:edubart/nelua-lang.git cd nelua-lang ``` -Now can run it doing: +Now you can run it: ```bash nelua examples/helloworld.nelua ``` -When running you should get an output similar to this: +When running it you should get an output that looks like this: ```bash generated /home/user/nelua-lang/nelua_cache/examples/helloworld.c gcc -o "/home/user/nelua-lang/nelua_cache/examples/helloworld" \ @@ -46,50 +46,50 @@ gcc -o "/home/user/nelua-lang/nelua_cache/examples/helloworld" \ hello world ``` -Note that the compiler has generated the `helloworld.c`, -this is your program translated to C source code, -if you know how to read C then I encourage to open it and have a look, -the compiler tries to generate efficient, compact and readable C sources. +Note that the compiler has generated a file called `helloworld.c`. +This is your program translated to C source code. +If you know how to read C then I encourage you to open it and have a look. +The compiler tries to generate efficient, compact, and readable C sources. -After the C source file was generated GCC is invoked to compile the C sources +After the C source file is generated, GCC is invoked to compile the C sources, and then the program is executed. -If your machine does not have GCC you can use other C compiler using the flag `--cc`. -For example if you are on MacOS you probability want to use Clang then -do `nelua --cc clang examples/helloworld.nelua`, -or if you are on Windows you probably want to use MinGW then +If your machine does not have GCC, you can use another C compiler with the flag `--cc`. +For example, if you are on MacOS, you probably want to use Clang. In that case +do `nelua --cc clang examples/helloworld.nelua`. +If you are on Windows, you probably want to use MinGW, so do `nelua --cc x86_64-w64-mingw32-gcc examples/helloworld.nelua`. ## Syntax highlighting for editors -Syntax definitions for the language is available for -Visual Studio Code in [nelua-vscode](https://github.com/edubart/nelua-vscode) and -for Sublime Text in [nelua-sublime](https://github.com/edubart/nelua-sublime). -At the moment only Sublime Text have full definition, so I recommend using it. -If you use other code editor you can use Lua syntax highlighting, -as it very similar but of course incomplete. +Syntax definitions for the language are available for +Visual Studio Code with [nelua-vscode](https://github.com/edubart/nelua-vscode) and +for Sublime Text with [nelua-sublime](https://github.com/edubart/nelua-sublime). +At the moment, only Sublime Text has a full definition, so I recommend using it. +If you use another code editor you can use Lua syntax highlighting, +as it very similar (but of course, incomplete). I recommend using the syntax highlighter, -it makes the experience of playing around with the language more pleasant because +as it makes the experience of playing around with the language more pleasant, since it can highlight type notations. ## Language features -A quick tour of the language features can be seen in the [overview page](/overview/), -highly recommend to read it if you haven't yet. +A quick tour of the language features can be found in the [overview page](/overview/), +I highly recommend reading it if you haven't yet. ## More examples -As the language is being developed this tutorial still quite short. -However you can see and run more interesting examples of the language usage in the +As the language is being developed, this tutorial is quite short. +However you can see and run more interesting examples of the language in the [examples](https://github.com/edubart/nelua-lang/tree/master/examples), -[benchmarks](https://github.com/edubart/nelua-lang/tree/master/benchmarks) or +[benchmarks](https://github.com/edubart/nelua-lang/tree/master/benchmarks), or [tests](https://github.com/edubart/nelua-lang/tree/master/tests) folders. The most interesing examples are: * `examples/fibonacci.nelua` multiple implementations of the classic [Fibonnaci sequence](https://en.wikipedia.org/wiki/Fibonacci_number) -* `examples/brainfuck.nelua` use of meta-programing to code the esoteric [Brainfuck language](https://en.wikipedia.org/wiki/Brainfuck) +* `examples/brainfuck.nelua` use of metaprogramming to code the esoteric [Brainfuck language](https://en.wikipedia.org/wiki/Brainfuck) * `examples/snakesdl.nelua` the classic Snake game (requires SDL) * `examples/condots.nelua` connected dots graphic animation made in parallel (requires SDL and OpenMP)