Skip to content

Commit

Permalink
Merge branch 'develop' of github.com:Tablam/TablaM into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
mamcx committed Aug 30, 2020
2 parents 8fa56e1 + 7403766 commit 6dc7839
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 32 deletions.
31 changes: 18 additions & 13 deletions docs/content/syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,21 @@ The syntax is made to be learned quickly, and be as consistent as possible.

```sql
-- Comments start with 2 'minus' symbol
--- Multiline
commentaries
---
```

## Declarations

By *default*, the values are immutable except if explicitly marked as mutable **(TBD)**. To declare a value you write:

```swift
let x := 1 -- inmmutable
let x := 1 -- immutable aka: final (java), const (js), it cannot be updated
var x := 1 -- mutable
```

Note how to *assign a value* is used the operator `:=`. This is different to `=` that is used to *compare for equality*.
Note how to ***assign a value*** is used the operator `:=`. This is different to `=` that is used to ***compare for equality***.

## Literals

Expand All @@ -39,11 +42,11 @@ Literals are values that are typed directly in the source code, and are the most
1.0f --64 bit floats (base 2, requiered explicit suffix)
```

Note how the `Decimal` is the default floating point number, instead of the `float`, that is more common.
Note how the `Decimal` is the **default floating point number**, instead of the `float`, that is more common.

This mean **TablaM** is tailored to do [more exact arithmetic](https://stackoverflow.com/questions/618535/difference-between-decimal-float-and-double-in-net) for business/financial purposes, instead of default for engineering like most languages.

With numbers it is possible to do some
With numbers it is possible to do some arithmetic and assignment operators

### Math

Expand All @@ -53,6 +56,8 @@ With numbers it is possible to do some
2.0f * 10.0f -- = 20.0f
10 / 2 -- = 5.0
1 + 2.0 -- Error: Type mismatch Int <> Dec
let num := 1
num += 1 -- arithmetic and assignment operators (TBD)
```

**TablaM** doesn't do invisible conversions of values. Is necessary to explicitly cast values to mix them. (**TBD**).
Expand All @@ -63,7 +68,7 @@ Similar to array languages/libraries like APL/kdb+/NumPy, the operators know how
1 + 1 -- Scalar + Scalar
1 + [1; 2; 3] -- Scalar + Vector
[1; 2] + [3; 4] -- Vector + Vector, same rank
[1] + [3; 4] -- ERROR
[1] + [3; 4] -- ERROR, different rank 1 <> 2
```

### Booleans
Expand All @@ -73,13 +78,13 @@ true
false
```

With boolean values we can do *boolean expressions*, so we can
With Boolean values we can do *Boolean expressions*, so we can

### Compare values (**TBD**):

```python
1 == 1 -- = true
1 != 1 -- = false
1 = 1 -- = true
1 <> 1 -- = false

1 > 2 -- = false
1 >= 2 -- = false
Expand Down Expand Up @@ -129,7 +134,7 @@ t"08:00:00" -- Just time

## Types

**TablaM** use a *static type system*, meaning all values are assigned a *type* and is not possible to use values where it doesn’t work (**TBD**, *for now the types are checked at runtime*).
**TablaM** use a *static type system*, meaning all values are assigned a *type* and is not possible to use values where it doesn’t work (**TBD**, *for **now** the types are checked at runtime*).

Types are described in *TitleCase* like this:

Expand Down Expand Up @@ -227,7 +232,7 @@ Note the use of `[||]` to enclose the data, that it must be preceded by the type

## Relational operators

The *relational operators* are the second most distinctive feature of the language. Them are *intrinsically* part of the relational model. Where exist a relation, you can be sure you can apply *ALL* the relational operators. Them are [described in their own page](/operators).
The *relational operators* are the second most distinctive feature of the language. Them are *intrinsically* part of the relational model. Where exist a relation, you can be sure you can apply *ALL* the relational operators. Them are **[described in their own page](/operators)**.

All relational operators must start with the operator *query* `?`.

Expand Down Expand Up @@ -259,7 +264,7 @@ print(1)
sum([1;2;3])
```

The available functions are [described in their own page](/functions).
The available functions are **[described in their own page](/functions).**

## Control flow

Expand All @@ -280,7 +285,7 @@ Note how you can return the last value in each if branch.

However, this is not possible for looping constructs, these return the "pass" value. Is similar to the void in other languages.

### while
### while (TBD)

```rust
while true do
Expand All @@ -289,7 +294,7 @@ end
-- return pass
```

### for
### for (TBD)

```rust
for i in 1..10 do --this count from 1 to 9
Expand Down
38 changes: 19 additions & 19 deletions docs/content/tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ You probably have guessed a lot of things just looking at this table. It looks l

This is what makes the relational model its power. Is fairly "visual" and considers the data (relations) as "[first-class citizen](https://en.wikipedia.org/wiki/First-class_citizen)". But also, exist many other things that the relation tell us about:

- It has a header that labels the columns (*name*, *price*, *qty*)
- It has columns, and their values are *homogeneous*
- It has rows, and their value (the whole row), represents a single entity of the relation
- It has a header that **labels** the columns (*name*, *price*, *qty*)
- It has columns, and their values are ***homogeneous***
- It has rows, and their value (the whole row), represents a **single entity** of the relation

## Write the first program

Expand All @@ -55,17 +55,17 @@ let sales:= [
Let's explain what all that text means:

- `let sales` create an immutable (read-only) binding named "sales"
- `:=` is the assignment operator. It put in the *left* what is on the *right* of it.
- `:=` is the **assignment operator**. It put in the *left* what is on the *right* of it.
- Enclosed in `[]` is the relation, stored as a *vector*. Vectors are one of the ways to store data in computer memory. If you come from another language it could look strange to see that the vector allows rows and columns, instead of *only* flat values like `[1;2;3]`. But remember that this is a relational language!
- The first line declares the header or schema of the relation, with pairs of *names* & *types*. Types are, among other things, ways to define what kind of value the data/column *is*.
- The first line declares the **header or schema** of the relation, with pairs of *names* & *types*. Types are, among other things, ways to define what kind of value the data/column *is*.

| name | type | type usage |
| ----- | ------------------------------------------------------------ | ------------------------------------------------------------ |
| name | [Str](https://en.wikipedia.org/wiki/UTF-8) | For text, data in UTF8 format |
| price | [Dec](https://en.wikipedia.org/wiki/Decimal_data_type) | For numbers, as 64 bit decimals, like money |
| qty | [Int](https://en.wikipedia.org/wiki/Integer_%28computer_science%29) | For numbers, as 64 bit integers, like quantities, positions, counts, etc |

- The next lines are the "rows". It must match the type of their column.
- The next lines are the *"**rows**"*. It must match the type of their column.

Now with this data, we can do a lot of stuff, thanks to:

Expand All @@ -89,22 +89,22 @@ print(products)
### ?where
The `?where` operator (aka: selection or `where...` in SQL), allow filtering *the rows* in a relation. It needs a "*boolean expression*", ie: expression that compares values, columns or returns true/false.
The `?where` operator (aka: selection or `where...` in SQL), allow filtering *the rows* in a relation. It needs a "Boolean expression*", i.e.: expression that compares values, columns or returns true/false. The `=` is the equal operator, more [logical operators](/syntax/#compare-values-tbd).
```rust
let soda := sales ?where #name == "Soda"
let soda := sales ?where #0 == "Soda"
-- let soda := sales ?where #name = "Soda" (TBD)
let soda := sales ?where #0 = "Soda" -- #0 is #name column
let cheaper := sales ?where #price < 5.0
let cheaper := sales ?where #1 < 5.0 -- #1 is #price column
```
## Some math
Now we can start to do more stuff. We can know how many money we get for this sale:
Now we can start to do more stuff. We can know how many money we get for this sale:
```rust
let profit_items := sales?select #price * #qty
let profit_items := sales?select #price * #qty -- arithmetic operations in relational operators (TBD)
print(profit_items)
let profit_total := sum(profit_items)
print(profit_total)
Expand All @@ -120,15 +120,15 @@ print(most)
Note how each operation work in relations and return relations.
Single values like `1` or `"Soda"` are also relations. Also know as "[scalars](https://en.wikipedia.org/wiki/Variable_(computer_science))". **TablaM** considers it relations of 1 column, 1 row, and 1 cell.
Single values like `1` or `"Soda"` are also relations. Also know as "[scalars](https://en.wikipedia.org/wiki/Variable_(computer_science))". **TablaM** considers it relations of 1 whole column, 1 whole row and 1 cell.
This mean that this is possible:
```rust
let price := 1.0 ?select #0
```
Now, we can continue with the program and make it more useful. We said before that the values are "*immutable*" by default. This mean that if we want to change them we need to create *new* values from the *olds*. Let's add another sale:
Now, we can continue with the program and make it more useful. We said before that the values are "***immutable***" by default. This mean that if we want to change them we need to create *new* values from the *olds*. Let's add another sale:

```rust
let new_sale := ["Hot dog", 4.0, 1]
Expand All @@ -144,20 +144,20 @@ Well, is because **TablaM** use a neat trick: Their values are not only typed, b
// In rust, a nominal typed language
struct SalesA {name:Str, price:Dec, qty:Int}
struct SalesB {name:Str, price:Dec, qty:Int}
let a = SalesA::new("Hot dog", 4.0, 1)
let b = SalesB::new("Hot dog", 4.0, 1)
a == b //false
let a := SalesA::new("Hot dog", 4.0, 1)
let b := SalesB::new("Hot dog", 4.0, 1)
a = b //false
```

Instead, in TablaM, two things are equal if their *schema/header* match:
Instead, in **TablaM**, two things are equal if their *schema/header* match:

```rust
-- In TablaM, a structural typed language
let a := ["Hot dog", 4.0, 1]
-- is automatically infered the header [name:Str, price:Dec, qty:Int;]

let b := [name:Str, price:Dec, qty:Int; "Hot dog", 4.0, 1]
a = b //true!
a = b -- true!
```

**Comming soon in "TablaM, the awesome programming language":**
Expand Down
9 changes: 9 additions & 0 deletions lang/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ impl<'source> Parser<'source> {
| Some(Token::Skip)
| Some(Token::Distinct)
| Some(Token::Deselect) => self.parse_query(name.into())?,
Some(Token::Assignment) => self.parse_var_assignment(name)?,
_ => Expression::Variable(name.into()),
}
}
Expand Down Expand Up @@ -273,6 +274,14 @@ impl<'source> Parser<'source> {
Err(result.err().unwrap())
}

fn parse_var_assignment(&mut self, name: &str) -> Return {
self.accept();
return Ok(Expression::Mutable(
name.to_string(),
Box::new(self.parse_ast(0)?),
));
}

fn parse_parameter_definition(&mut self, name: &str) -> Return {
self.accept();
let result = self.check_and_accept_next(Token::Type(String::from("")));
Expand Down

0 comments on commit 6dc7839

Please sign in to comment.