Skip to content

Commit

Permalink
Some better parser, actually good error reporting
Browse files Browse the repository at this point in the history
  • Loading branch information
3top1a committed Jan 15, 2025
1 parent fbd901d commit 398c0b5
Show file tree
Hide file tree
Showing 8 changed files with 339 additions and 191 deletions.
29 changes: 17 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
# Alkoholiq

Alcoholiq, a programming language that transpiles to Brainfuck.
Alkoholiq, a programming language that transpiles to Brainfuck.
The output is not executable immediately, and needs to be piped into a tool such as [my 540 byte brainfuck interpreter](https://github.com/3top1a/sbfi-rs).

The ultimate goal for this semi-esoteric language is to be able to write itself in a readable way, with sytnax similar
The ultimate goal for this semi-esoteric language is to be able to write itself in a readable way, with syntax similar
to rust and operation similar to C.

## Syntax

The only valid file extension is .🍺 (U+1F37A).

Not all features of this section's example are implemented.
Syntax may also change, I maybe might possibly try to think about doing math properly.
Syntax may also change, I might possibly maybe try to think about doing math properly someday for three seconds.

```js
// Comment
Expand Down Expand Up @@ -59,36 +59,41 @@ input(input_array, 16)
print("Hello ")
print(input_array)
print("!\n")
// Printf is used for printing strings and numbers in decimal
// This prints `c`
print(c)
// This prints `99`
printf(c)

// Raw Brainfuck
// This should only be used in the standard library, e.g. input(), not in user code
// If this project succeeds it's ultimate goal, basm will be the only function from the compiler except math,
// and all other functions will be written in alkoholiq
// If this project succeeds it's ultimate goal, basm will be the only function from
// the compiler except math, and all other functions will be written in alkoholiq
basm("<>+-")

// Iterators work like in Rust
for ch in input_array {
// Indents are 8 wide tabs
print(ch);
print('\n');
printf(ch);
printf('\n');
}

// Example foobar implementation
hit = false
for i in 0..254 {
if %(i, 5) == 0 {
hit = true
print("Foo")
printf("Foo")
}
if %(i, 7) == 0 {
hit = true
print("Bar")
printf("Bar")
}
if hit == true {
print("\n")
printf("\n")
} else {
print(i)
print('\n')
printf(i)
printf('\n')
}
}

Expand Down
5 changes: 4 additions & 1 deletion examples/basic.🍺
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ named_char = 'c'
// false is 0, true is 1
// In comparison, 0 is false, everything else is true
bool = true
// ! negates the value
// Since it's just numbers, it's simply |(0 - x)|
bool = !bool

// Fixed size arrays
// Arrays are denoted by the * symbol as they work like pointers
Expand All @@ -36,7 +39,7 @@ math = +( 5 *( 5 two ) )
input_array = [0; 16]
// Get user input
// Maximum length is 16
input(input_array, 16)
input(input_array 16)

// Print
print("Hello ")
Expand Down
2 changes: 1 addition & 1 deletion justfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ lint:

test: build
cargo test
cargo run --release -- examples/*
for x in examples/*; do cargo run --release -- $x; done
48 changes: 37 additions & 11 deletions src/ast.rs
Original file line number Diff line number Diff line change
@@ -1,28 +1,43 @@
#[derive(Debug, PartialEq, Clone)]
pub enum Expression {
// Literals
/// Numeric literal
/// Doubles as a ASCII character literal, for Unicode an Array of these is used instead.
/// Doubles as an ASCII character literal, for Unicode an Array of these is used instead.
/// Also used for boolean literals, where 0 is false and 1 is true.
/// In comparison, x == true is equivalent to x != 0 and will match any non-zero.
Number(u8),
/// Array
/// Array literal
Array(Vec<Expression>),

/// A literal identifier
Identifier(String),
/// A path denotes a variable
Path(String),

/// A function call
Call {
/// Name of the function
name: String,
/// Arguments
args: Vec<Expression>,
},

/// Unary arithmetic operation
Unary {
/// Operator
op: UnaryOperator,
/// Operand
operand: Box<Expression>,
},

/// Basic arithmetic operation
Arithmetic {
/// Since the output is a number anyway, we can group comparisons with arithmetic operations.
Binary {
/// Left side
left: Box<Expression>,
lhs: Box<Expression>,
/// Operator
op: MathOperator,
/// Right side
right: Box<Expression>,
rhs: Box<Expression>,
},

/// Assignment
/// Variable assignment
Assignment {
/// Name of the variable
name: String,
Expand All @@ -31,7 +46,7 @@ pub enum Expression {
},

/// Closure
Closure {
Expression {
/// Body
body: Vec<Expression>,
},
Expand All @@ -43,4 +58,15 @@ pub enum MathOperator {
Subtract,
Multiply,
Divide,
Equals,
NotEquals,
LessThan,
GreaterThan,
}

#[derive(Debug, PartialEq, Clone)]
pub enum UnaryOperator {
/// Negate a number
/// Works by subtracting the number from 0 and returning the absolute value.
Negate,
}
Loading

0 comments on commit 398c0b5

Please sign in to comment.