ref: a9a7d5b32a9423f871311384af6260a3848291d1
parent: 21ead16ccde2a943abe68ef279c89dbff030cb87
author: Ori Bernstein <ori@eigenstate.org>
date: Sun Jan 15 18:07:33 EST 2017
Split Syntax from type rules.
--- a/doc/lang.txt
+++ b/doc/lang.txt
@@ -13,16 +13,17 @@
3.1. Summary
4. SYNTAX
4.1. Declarations
- 4.2. Data Types
- 4.3. Literal Values
- 4.4. Blocks
- 4.5. Control Constructs
- 4.6. Expressions
- 4.7. Type Inference
- 4.8. Generics
- 4.9. Traits
- 4.10. Packages and Uses
- 5. GRAMMAR
+ 4.2. Literal Values
+ 4.3. Blocks
+ 4.4. Control Constructs
+ 4.5. Expressions
+ 4.6. Packages and Uses
+ 5. TYPES
+ 5.1. Data Types
+ 5.2. Type Inference
+ 5.3. Traits
+ 5.4. Generics
+ 6. GRAMMAR
1. ABOUT:
@@ -204,144 +205,6 @@
- 4.2. Data Types:
-
- The language defines a number of built in primitive types. These
- are not keywords, and in fact live in a separate namespace from
- the variable names. Yes, this does mean that you could, if you want,
- define a variable named 'int'.
-
- There are no implicit conversions within the language. All types
- must be explicitly cast if you want to convert, and the casts must
- be of compatible types, as will be described later.
-
- 4.2.1. Primitive types:
-
- void
- bool char
- int8 uint8
- int16 uint16
- int32 uint32
- int64 uint64
- int uint
- long ulong
- float32 float64
-
- These types are as you would expect. 'void' represents a
- lack of type, although for the sake of genericity, you can
- assign between void types, return values of void, and so on.
- This allows generics to not have to somehow work around void
- being a toxic type. The void value is named `void`.
-
- It is interesting to note that these types are not keywords,
- but are instead merely predefined identifiers in the type
- namespace.
-
- bool is a type that can only hold true and false. It can be
- assigned, tested for equality, and used in the various boolean
- operators.
-
- char is a 32 bit integer type, and is guaranteed to be able
- to hold exactly one codepoint. It can be assigned integer
- literals, tested against, compared, and all the other usual
- numeric types.
-
- The various [u]intXX types hold, as expected, signed and
- unsigned integers of the named sizes respectively.
- Similarly, floats hold floating point types with the
- indicated precision.
-
- var x : int declare x as an int
- var y : float32 declare y as a 32 bit float
-
-
- 4.2.2. Composite types:
-
- pointer
- slice array
-
- Pointers are, as expected, values that hold the address of
- the pointed to value. They are declared by appending a '#'
- to the type. Pointer arithmetic is not allowed. They are
- declared by appending a '#' to the base type
-
- Arrays are a group of N values, where N is part of the type.
- Arrays of different sizes are incompatible. Arrays in
- Myrddin, unlike many other languages, are passed by value.
- They are declared by appending a '[SIZE]' to the base type.
-
- Slices are similar to arrays in many contemporary languages.
- They are reference types that store the length of their
- contents. They are declared by appending a '[,]' to the base
- type.
-
- foo# type: pointer to foo
- foo[123] type: array of 123 foo
- foo[,] type: slice of foo
-
- 4.2.3. Aggregate types:
-
- tuple struct
- union
-
- Tuples are the traditional product type. They are declared
- by putting the comma separated list of types within square
- brackets.
-
- Structs are aggregations of types with named members. They
- are declared by putting the word 'struct' before a block of
- declaration cores (ie, declarations without the storage type
- specifier).
-
- Unions are the traditional sum type. They consist of a tag
- (a keyword prefixed with a '`' (backtick)) indicating their
- current contents, and a type to hold. They are declared by
- placing the keyword 'union' before a list of tag-type pairs.
- They may also omit the type, in which case, the tag is
- sufficient to determine which option was selected.
-
- [int, int, char] a tuple of 2 ints and a char
-
- struct a struct containing an int named
- a : int 'a', and a char named 'b'.
- b : char
- ;;
-
- union a union containing one of
- `Thing int int or char. The values are not
- `Other float32 named, but they are tagged.
- ;;
-
-
- 4.2.4. Magic types:
-
- tyvar typaram
- tyname
-
- A tyname is a named type, similar to a typedef in C, however
- it genuinely creates a new type, and not an alias. There are
- no implicit conversions, but a tyname will inherit all
- constraints of its underlying type.
-
- A typaram is a parametric type. It is used in generics as
- a placeholder for a type that will be substituted in later.
- It is an identifier prefixed with '@'. These are only valid
- within generic contexts, and may not appear elsewhere.
-
- A tyvar is an internal implementation detail that currently
- leaks in error messages out during type inference, and is a
- major cause of confusing error messages. It should not be in
- this manual, except that the current incarnation of the
- compiler will make you aware of it. It looks like '@$type',
- and is a variable that holds an incompletely inferred type.
-
- type mine = int creates a tyname named
- 'mine', equivalent to int.
-
-
- @foo creates a type parameter
- named '@foo'.
-
4.3. Literal Values
4.3.1. Atomic Literals:
@@ -766,8 +629,191 @@
signed types, and fill with zeros on unsigned types.
- 4.7. Type Inference:
+
+ 4.8. Packages and Uses:
+
+ pkg use
+
+ There are two keywords for module system. 'use' is the simpler
+ of the two, and has two cases:
+
+ use syspkg
+ use "localfile"
+
+ The unquoted form searches all system include paths for 'syspkg'
+ and imports it into the namespace. By convention, the namespace
+ defined by 'syspkg' is 'syspkg', and is unique and unmerged. This
+ is not enforced, however. Typical usage of unquoted names is to
+ import a library that already exists.
+
+ The quoted form searches the local directory for "localpkg". By
+ convention, the package it imports does not match the name
+ "localpkg", but instead is used as partial of the definition of the
+ importers package. This is a confusing description.
+
+ A typical use of a quoted import is to allow splitting one package
+ into multiple files. In order to support this behavior, if a package
+ is defined in the current file, and a use statements imports a
+ package with the same namespace, the two namespaces are merged.
+
+ The 'pkg' keyword allows you to define a (partial) package by
+ listing the symbols and types for export. For example,
+
+ pkg mypkg =
+ type mytype
+
+ const Myconst : int = 42
+ const myfunc : (v : int -> bool)
+ ;;
+
+ declares a package "mypkg", which defines three exports, "mytype",
+ "Myconst", and "myfunc". The definitions of the values may be
+ defined in the 'pkg' specification, but it is preferred to implement
+ them in the body of the code for readability. Scanning the export
+ list is desirable from a readability perspective.
+
+5. TYPES:
+
+ 4.2. Data Types:
+
+ The language defines a number of built in primitive types. These
+ are not keywords, and in fact live in a separate namespace from
+ the variable names. Yes, this does mean that you could, if you want,
+ define a variable named 'int'.
+
+ There are no implicit conversions within the language. All types
+ must be explicitly cast if you want to convert, and the casts must
+ be of compatible types, as will be described later.
+
+ 4.2.1. Primitive types:
+
+ void
+ bool char
+ int8 uint8
+ int16 uint16
+ int32 uint32
+ int64 uint64
+ int uint
+ long ulong
+ float32 float64
+
+ These types are as you would expect. 'void' represents a
+ lack of type, although for the sake of genericity, you can
+ assign between void types, return values of void, and so on.
+ This allows generics to not have to somehow work around void
+ being a toxic type. The void value is named `void`.
+
+ It is interesting to note that these types are not keywords,
+ but are instead merely predefined identifiers in the type
+ namespace.
+
+ bool is a type that can only hold true and false. It can be
+ assigned, tested for equality, and used in the various boolean
+ operators.
+
+ char is a 32 bit integer type, and is guaranteed to be able
+ to hold exactly one codepoint. It can be assigned integer
+ literals, tested against, compared, and all the other usual
+ numeric types.
+
+ The various [u]intXX types hold, as expected, signed and
+ unsigned integers of the named sizes respectively.
+ Similarly, floats hold floating point types with the
+ indicated precision.
+
+ var x : int declare x as an int
+ var y : float32 declare y as a 32 bit float
+
+
+ 4.2.2. Composite types:
+
+ pointer
+ slice array
+
+ Pointers are, as expected, values that hold the address of
+ the pointed to value. They are declared by appending a '#'
+ to the type. Pointer arithmetic is not allowed. They are
+ declared by appending a '#' to the base type
+
+ Arrays are a group of N values, where N is part of the type.
+ Arrays of different sizes are incompatible. Arrays in
+ Myrddin, unlike many other languages, are passed by value.
+ They are declared by appending a '[SIZE]' to the base type.
+
+ Slices are similar to arrays in many contemporary languages.
+ They are reference types that store the length of their
+ contents. They are declared by appending a '[,]' to the base
+ type.
+
+ foo# type: pointer to foo
+ foo[123] type: array of 123 foo
+ foo[,] type: slice of foo
+
+ 4.2.3. Aggregate types:
+
+ tuple struct
+ union
+
+ Tuples are the traditional product type. They are declared
+ by putting the comma separated list of types within square
+ brackets.
+
+ Structs are aggregations of types with named members. They
+ are declared by putting the word 'struct' before a block of
+ declaration cores (ie, declarations without the storage type
+ specifier).
+
+ Unions are the traditional sum type. They consist of a tag
+ (a keyword prefixed with a '`' (backtick)) indicating their
+ current contents, and a type to hold. They are declared by
+ placing the keyword 'union' before a list of tag-type pairs.
+ They may also omit the type, in which case, the tag is
+ sufficient to determine which option was selected.
+
+ [int, int, char] a tuple of 2 ints and a char
+
+ struct a struct containing an int named
+ a : int 'a', and a char named 'b'.
+ b : char
+ ;;
+
+ union a union containing one of
+ `Thing int int or char. The values are not
+ `Other float32 named, but they are tagged.
+ ;;
+
+
+ 4.2.4. Generic types:
+
+ tyvar typaram
+ tyname
+
+ A tyname is a named type, similar to a typedef in C, however
+ it genuinely creates a new type, and not an alias. There are
+ no implicit conversions, but a tyname will inherit all
+ constraints of its underlying type.
+
+ A typaram is a parametric type. It is used in generics as
+ a placeholder for a type that will be substituted in later.
+ It is an identifier prefixed with '@'. These are only valid
+ within generic contexts, and may not appear elsewhere.
+
+ A tyvar is an internal implementation detail that currently
+ leaks in error messages out during type inference, and is a
+ major cause of confusing error messages. It should not be in
+ this manual, except that the current incarnation of the
+ compiler will make you aware of it. It looks like '@$type',
+ and is a variable that holds an incompletely inferred type.
+
+ type mine = int creates a tyname named
+ 'mine', equivalent to int.
+
+
+ @foo creates a type parameter
+ named '@foo'.
+ 5.2. Type Inference:
+
The myrddin type system is a system similar to the Hindley Milner
system, however, types are not implicitly generalized. Instead, type
schemes (type parameters, in Myrddin lingo) must be explicitly provided
@@ -850,52 +896,7 @@
|| && == !=
< <= > >=
-
- 4.8. Packages and Uses:
-
- pkg use
-
- There are two keywords for module system. 'use' is the simpler
- of the two, and has two cases:
-
- use syspkg
- use "localfile"
-
- The unquoted form searches all system include paths for 'syspkg'
- and imports it into the namespace. By convention, the namespace
- defined by 'syspkg' is 'syspkg', and is unique and unmerged. This
- is not enforced, however. Typical usage of unquoted names is to
- import a library that already exists.
-
- The quoted form searches the local directory for "localpkg". By
- convention, the package it imports does not match the name
- "localpkg", but instead is used as partial of the definition of the
- importers package. This is a confusing description.
-
- A typical use of a quoted import is to allow splitting one package
- into multiple files. In order to support this behavior, if a package
- is defined in the current file, and a use statements imports a
- package with the same namespace, the two namespaces are merged.
-
- The 'pkg' keyword allows you to define a (partial) package by
- listing the symbols and types for export. For example,
-
- pkg mypkg =
- type mytype
-
- const Myconst : int = 42
- const myfunc : (v : int -> bool)
- ;;
-
- declares a package "mypkg", which defines three exports, "mytype",
- "Myconst", and "myfunc". The definitions of the values may be
- defined in the 'pkg' specification, but it is preferred to implement
- them in the body of the code for readability. Scanning the export
- list is desirable from a readability perspective.
-
-9. GRAMMAR:
-
-10. FUTURE DIRECTIONS:
+6. GRAMMAR:
BUGS: