Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion docs/grammar.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,22 @@ Non-terminals are lowercase words.

program -> declaration* EOF ;

/* returns a SlashType, not a an AST node */
type_hint -> ":" TYPE ;

newline -> ( "\n" | ";" )+ ;

expr_promotion -> newline | "}" | "&&" | "||" ;

declaration -> var_declaration
| and_or ;

var_declaration -> "var" IDENTIFIER "=" expression newline ;
var_declaration -> "var" IDENTIFIER type_hint? "=" expression newline ;

and_or -> statement ( ( "&&" | "||" ) statement )* ;



/* statements */

statement -> loop_stmt
Expand Down
1 change: 1 addition & 0 deletions include/interpreter/ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ typedef struct {
typedef struct {
StmtType type;
StrView name;
SlashType type_hint; // optional: defaults to SLASH_ANY
Expr *initializer;
} VarStmt;

Expand Down
3 changes: 2 additions & 1 deletion include/interpreter/types/slash_value.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ typedef enum {
SLASH_TUPLE,
SLASH_MAP,
SLASH_NONE,
SLASH_TYPE_COUNT,
SLASH_TYPE_COUNT, /* not any actual type */
SLASH_ANY, /* special type that a value cannot hold in runtime */
} SlashType;

#define SLASH_TYPE_DYNAMIC(slash_type) \
Expand Down
4 changes: 4 additions & 0 deletions src/interpreter/interpreter.c
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,10 @@ static void exec_expr(Interpreter *interpreter, ExpressionStmt *stmt)
static void exec_var(Interpreter *interpreter, VarStmt *stmt)
{
SlashValue value = eval(interpreter, stmt->initializer);
if (stmt->type_hint != SLASH_ANY && stmt->type_hint != value.type) {
report_runtime_error("Type mismatch. Expected X, but got Y.");
ASSERT_NOT_REACHED;
}
var_define(interpreter->scope, &stmt->name, &value);
}

Expand Down
22 changes: 20 additions & 2 deletions src/interpreter/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ static void report_err_and_sync(Parser *parser, char *err_msg);
* non-terminal grammar rule functions
*/

static SlashType type_hint(Parser *parser);
static void newline(Parser *parser);
static void expr_promotion(Parser *parser);
static Stmt *declaration(Parser *parser);
Expand Down Expand Up @@ -216,6 +217,16 @@ static void report_err_and_sync(Parser *parser, char *err_msg)


/* grammar functions */
static SlashType type_hint(Parser *parser)
{
/* came from ':' */
if (!match(parser, t_num, t_str, t_bool)) {
report_err_and_sync(parser, "Expected type keyword after ':'");
return SLASH_ANY;
}
return token_type_to_slash_type(previous(parser)->type);
}

static void newline(Parser *parser)
{
consume(parser, t_newline, "Expected newline or semicolon");
Expand Down Expand Up @@ -248,13 +259,20 @@ static Stmt *declaration(Parser *parser)
static Stmt *var_decl(Parser *parser)
{
/* came from 'var' */
VarStmt *stmt = (VarStmt *)stmt_alloc(parser->ast_arena, STMT_VAR);
Token *name = consume(parser, t_ident, "Expected variable name");
stmt->name = name->lexeme;

/* optional type */
if (match(parser, t_colon))
stmt->type_hint = type_hint(parser);
else
stmt->type_hint = SLASH_ANY;

consume(parser, t_equal, "Expected variable definition");
Expr *initializer = expression(parser);
expr_promotion(parser);

VarStmt *stmt = (VarStmt *)stmt_alloc(parser->ast_arena, STMT_VAR);
stmt->name = name->lexeme;
stmt->initializer = initializer;
return (Stmt *)stmt;
}
Expand Down
8 changes: 2 additions & 6 deletions src/test.slash
Original file line number Diff line number Diff line change
@@ -1,6 +1,2 @@
var list1 = ["Nicolai", "Callum", 2, "Aidan", 4, "Zach", "Brendan", 1]
$list1.sort()
var i = 0
loop item in $list1 {
echo $item
}
var s: str = "Nicolai"
echo $s