aboutsummaryrefslogtreecommitdiff
path: root/Specification.md
diff options
context:
space:
mode:
Diffstat (limited to 'Specification.md')
-rw-r--r--Specification.md465
1 files changed, 465 insertions, 0 deletions
diff --git a/Specification.md b/Specification.md
new file mode 100644
index 0000000..6eb095f
--- /dev/null
+++ b/Specification.md
@@ -0,0 +1,465 @@
+SLUL specification
+==================
+
+Copyright © 2026 Samuel Lidén Borell <samuel@kodafritt.se>
+
+SPDX-License-Identifier: EUPL-1.2+ OR LGPL-2.1-or-later
+
+
+1. Introduction
+===============
+
+1.1. Rationale
+--------------
+
+The SLUL language is meant to be:
+
+* Trustworthy from a user point of view; code should always have the minimum
+ necessary privileges and it should be memory safe without any loopholes.
+* As free as possible from recurring maintenance burdens; in particular,
+ changes in dependencies should not necessite additional tasks for the
+ dependent modules (such as rebuilds or code adaptations).
+* Have a low threshold for use; it should not require a large runtime
+ (technical threshold) or learning lots of new concepts or terminology
+ (knowledge threshold).
+
+This document defines the SLUL programming language and its execution
+environment.
+
+
+1.2. Organisation of the Document
+---------------------------------
+
+This document is structured in these parts:
+
+1. This introduction
+2. A high-level architecture overview
+3. Language Syntax and Semantics
+4. Module System
+5. Runtime Library
+6. Subsets and Extensions
+7. Binary Interface
+
+Cross-references are given in parentheses, for example (1.2) would refer to
+this section.
+
+
+1.3. Definitions
+----------------
+
+* Application
+* Execute
+* Giveme
+* Giveme Section
+* I/O
+* Library
+* Module
+* Runtime Loader
+* Top-Level
+
+2. Architecture Overview
+========================
+
+2.1. Modules
+------------
+
+A module is the highest unit for organising software. It can contain a number
+of top-level definitions (3.2; 3.3) such as classes. A module can either be
+an application module (2.1.1) or a library module (2.1.2).
+
+
+2.1.1. Application Modules
+--------------------------
+
+An application module must define at least one class that is a service (x.x.x).
+Each service provides one or more entry points (x.x.x) for the application.
+A such entry point can be called upon some environment-defined event, such as
+when the application is started, (in graphical applications) when a button
+is pressed, (in web applications) when a page is loaded, for example.
+
+Service classes may contain one `giveme` section (x.x.x) for dependency
+injection of, for example, I/O or parameters provided by the runtime.
+
+
+2.1.2. Library Modules
+----------------------
+
+A library module defines a interface that may be used from other modules
+(applications and as well as other libraries). An interface contains a set of
+exported classes and functions, that are defined in the interface file (x.x.x)
+of the library.
+
+Libraries can (and should) be versioned (x.x.x), and definitions may be tied
+to a specific versions. Versions and their definitions are immutable once
+released. From the definitions contained in given version, a so called
+"API hash" can be computed (x.x.x).
+
+
+2.2. The Parts Needed to Load an Application
+--------------------------------------------
+
+The following parts are necessary to load an application:
+
+* The application module (2.1.1).
+* Any library modules (2.1.2) needed by the program.
+* The runtime loader, which loads the main program as well as the library
+ modules. The runtime loader also processes the `giveme`
+ section (x.x.x) of each service class.
+
+
+2.2. Source Files in a Module
+-----------------------------
+
+A SLUL module consists of the following files:
+
+* The module source code (`.slul` files, except `interface.slul`)
+* For library modules, the interface definition file (`interface.slul`)
+* For library modules, an API index file (`api.index`)
+* A list of dependencies (`deps.index` file)
+* Optionally, a list of all `.slul` and `.index` files.
+
+Here is an example list of files in an application module:
+
+ deps.index
+ SomeCommand.slul
+
+Here is an example list of files in a library module:
+
+ deps.index
+ api.index
+ sources.index
+ interface.slul
+ SomeThing.slul
+
+Section (11.1) contains a list of restrictions on filenames.
+
+
+2.3. Interface Directories
+--------------------------
+
+In order to use a module as a dependency, it must have been copied into an
+interface directory with the filename corresponding to the module name, plus
+the `.slul` file extension.
+
+For interfaces contained unversioned definitions, the filename must instead
+have the format `modulename-apihash.slul`, where the API hash (x.x.x) is
+computed over all unversioned definitions with the preceeding version set to
+the last defined version (if any).
+
+The compiler looks for interfaces in the following order. Not all directories
+are applicable to all operating systems or environments:
+
+* Interface directories specified with compiler command-line options (10.1).
+* Per-user interface directories (x.x.x).
+* Local interface directories (x.x.x).
+* System interface directories (x.x.x).
+
+
+3. Language Syntax
+==================
+
+3.1. Valid Lexical Tokens
+-------------------------
+
+TODO
+
+
+3.2. Anatomy of a Module Source File
+------------------------------------
+
+A module source file whose filename begins with an uppercase letter is a
+source is a class file. The contents in a class file is considered to be part
+of a class (x.x.x) with the same name as the file, minus the directories and
+file extension.
+
+A module source file whose filename begins with a lowercase letter is called
+a utility file. In a utility file, definitions do not belong to any class.
+
+A class file may contain the following top-level definitions, in the following
+order:
+
+1. A service type definition (3.4.1) or a class definition qualifier (3.4.7.1)
+2. A `giveme` section (3.4.2)
+3. Any number of fields (3.4.3)
+4. Any number of constructors (3.4.4)
+5. Any number of functions (3.4.5)
+
+Top-level definitions may not be indented.
+
+
+3.3. Anatomy of an Interface File
+---------------------------------
+
+A library module must have an interface file, that describes the exported
+definitions. Exported definitions are made available to be used by other
+modules.
+
+TODO require interface files to begin with `library <modulename>`?
+
+An interface file may contain the following top-level definitions, in the
+following order:
+
+1. Optionally a `usetype` section (3.4.6)
+2. Any number of constants (3.4.3.1)
+3. Any number of class definitions (3.4.7)
+
+The classes may in turn contain the following top-level definitions, again
+in the following order:
+
+1. Any number of fields (3.4.3)
+2. Any number of constructors (3.4.4)
+3. Any number of functions (3.4.5)
+
+Note that unlike module source files, interface files do not contain `end`
+keywords, since top-level definitions automatically end where the next
+top-level definition begins.
+
+Top-level definitions may not be indented.
+
+
+3.4. Top-Level Definitions
+--------------------------
+
+3.4.1. Service Type Definitions
+3.4.2. `giveme` Sections
+3.4.3. Field Definitions
+3.4.3.1. Constant Definitions
+3.4.4. Constructor Definitions
+3.4.5. Function Definitions
+3.4.6. `usetype` Sections
+when an interface requests a type in `usetype` then any module, that
+depends on the interface, must also depend on the module that defines the type.
+3.4.7. Class Definitions
+3.4.7.1. Class Definition Qualifiers
+
+
+3.5. Identifier References
+--------------------------
+
+There are two types of identifiers: types, which start with an uppercase letter
+and function/data identifiers, which start with a lowercase letter.
+
+Identifiers can be defined and referenced in any order, except for local
+variables which have to be defined before use (x.x.x).
+
+Identifiers can only be defined once, and may not "shadow" another identifier
+in an outer scope. However, identifiers can exist with the same name if they
+are in different scopes that are not visible in either of the other scope.
+
+Each module has it's own namespace (x.x.x), and depending on a module only
+makes identifiers in the requested version visible, and they only become
+visible in the module/interface that requested them (x.x.x). See also `usetype`
+(3.4.6).
+
+
+3.6. Type References
+--------------------
+
+TODO Examples of type references
+
+ Int
+ List Int
+
+ Int i
+ List Int l
+ Map String Int m
+ Map String List Int ml
+ List Map String Int lm
+ GenericType1 (GenericType2 Int) String g
+
+TODO problems:
+
+* Make visual separation clearer between the type and what follows
+ after it.
+ - use double spaces?
+ Int i
+ List Int l
+ Map String Int m
+ Map String List Int ml
+ List Map String Int lm
+ GenericType1 (GenericType2 Int) String g
+ - use alignment?
+ Int i
+ List Int l
+ Map String Int m
+ Map String List Int ml
+ List Map String Int lm
+ GenericType1 (GenericType2 Int) String g
+ - use parentheses? but perhaps harder to parse?
+ (Int) i
+ (List Int) l
+ (Map String Int) m
+ (Map String List Int) ml
+ (List Map String Int) lm
+ (GenericType1 (GenericType2 Int) String) g
+ - use a terminator character/sequence?
+ Int: i
+ List Int: l
+ Map String Int: m
+ Map String List Int: ml
+ List Map String Int: lm
+ GenericType1 (GenericType2 Int) String: g
+ - use brackets/parantheses around the variable identifier?
+ Int [i]
+ List Int [l]
+ Map String Int [m]
+ Map String List Int [ml]
+ List Map String Int [lm]
+ GenericType1 (GenericType2 Int) String [g]
+ - allow writing generic types together(!):
+ Int i
+ ListInt l
+ MapStringInt m
+ MapStringListInt ml
+ ListMapStringInt lm
+ GenericType1(GenericType2Int)String g
+ - Use [] or <> like other proglangs (but should there be a comma?)?
+ Int i
+ List<Int> l
+ Map<String,Int> m
+ Map<String,List<Int>> ml
+ List<Map<String Int> lm
+ GenericType1<GenericType2<Int>,String> g
+ - Use [] between the base type and the type parameters?
+ (see `notes/combined_list_and_array.txt`).
+ And use concrete maps? (see next section)
+ Int i
+ List[]Int l
+ MapOfString[]Int m
+ MapOfString[]List[]Int ml
+ List[]MapOfString[]Int lm
+ GenericType1[](GenericType2[]Int)[]String g
+* How to call methods of objects of the parameter type?
+ - Add a possibility to require a specific type.
+ - Can it be done without a vtable? Maybe pass some info along with the
+ generic this/object parameters?
+ - Or don't do that at all, and have StringMap, IntMap, etc.
+ (which could have a more efficient encoding/lookup).
+ - But `StringMap Int` is "mixed endian".
+ - `MapOfString Int` ?
+ - `MapFromString Int` ?
+ - `MapFromStringTo Int` ?
+ - `MapStringTo Int` ?
+ - `FromStringTo Int` ?
+ - `LookupWithString Int` ?
+ - `LookupFromString Int` ?
+ - Or, even reverse the order? `Int StringMap`
+ - `Map_String Int` ?
+ - `LookupS`, `LookupI`
+ - Or avoid the problem:
+ - `NameMap`, `NumberMap`, `CustomMap`
+ - `NameLookup`, `NumberLookup`, `CustomLookup`
+ - there could also be `AsciiCaseInsensLookup` for example.
+ (but there are many combinations!)
+ - Or have "simple objects" that cannot have outgoing pointers,
+ and have a unique representation of each value, and hence only need
+ length in order to compare them?
+
+* TODO
+
+
+3.7. Function Code
+------------------
+
+* TODO
+
+
+4. Module System
+================
+
+* TODO
+ - describe the module system
+ - describe interface files
+ - describe API hash computation
+* TODO language semantics section (section 5?)
+* TODO
+
+5. Semantic Checks and Program Behaviour
+========================================
+
+* TODO
+
+
+6. Runtime Library
+==================
+
+* TODO
+
+
+7. Subsets and Extensions
+=========================
+
+* TODO
+ - how to "invoke" a subset or extension in a module
+ - the bootstrapping subset
+ - extensions (which ones should be extensions, and which ones should be
+ built-in?)
+ - int64?
+ - integer wrap-around?
+ - floating point (different formats, could be several extensions)
+ - vector?
+
+
+8. Repositories
+===============
+
+x.x.x. Local Repositories
+-------------------------
+
+TODO /usr/share/slul-interfaces, /usr/local, ~/.local, %COMMONFILES%, ...
+
+
+9. Binary Interface
+===================
+
+* TODO
+ - general considerations / rationale
+ - common definitions
+ - SYS-V based interface
+ - Win32/64 based interface?
+ - WASI based interface?
+
+
+10. Compiler Command-Line Syntax
+===============================
+
+TODO
+
+
+11. Details
+===========
+
+11.1. Restrictions on Filenames
+-------------------------------
+
+The purpose of these rules is to support a wide variety of file systems.
+
+Filenames are case-sensitive and must use only English letters a-z (uppercase
+and lowercase), digits 0-9 and underscores "_", followed by a dot "." and a
+lowercase file extension.
+
+The first character in a filename must always be a letter (not a digit,
+dot or underscore).
+
+Each file or directory must have a filename that is case-insensitive distinct
+from all other filenames.
+
+No files may have any of the following names, case-insensitive, before the
+file extension:
+
+* `aux`
+* `com` followed by a digit 0-9
+* `con`
+* `lpt` followed by a digit 0-9
+* `lst`
+* `nul`
+* `prn`
+
+The total length of a filename, including directory names and a 1 character
+separator after each directory, may not exceed 100 characters.
+
+
+11.2. API hash computation
+--------------------------
+
+TODO