diff --git a/.ruby-version b/.ruby-version
deleted file mode 100644
index 9c25013..0000000
--- a/.ruby-version
+++ /dev/null
@@ -1 +0,0 @@
-3.3.6
diff --git a/boot/parser.yy b/boot/parser.yy
index e4b4f08..74f2e19 100644
--- a/boot/parser.yy
+++ b/boot/parser.yy
@@ -530,7 +530,7 @@ variable_declarations:
             $$.reserve($$.size() + $3.size());
             $$.insert(std::end($$), std::begin($3), std::end($3));
         }
-    | variable_declaration { std::swap($$, $1); }
+    | /* no variable declarations */ {}
 variable_part:
     /* no variable declarations */ {}
     | "var" variable_declarations { std::swap($$, $2); }
@@ -553,9 +553,9 @@ type_definition: identifier_definition "=" type_expression
             $$ = new boot::type_definition(boot::make_position(@1), $1.first, $1.second, $3);
         }
 type_definitions:
-    type_definition type_definitions
+    type_definition ";" type_definitions
         {
-            std::swap($$, $2);
+            std::swap($$, $3);
             $$.insert($$.cbegin(), $1);
         }
     | /* no type definitions */ {}
diff --git a/source.elna b/source.elna
index 02afc8e..695b0e1 100644
--- a/source.elna
+++ b/source.elna
@@ -67,23 +67,23 @@ type
   Position* = record
     line: Word;
 	column: Word
-  end
+  end;
   Location* = record
     first: Position;
 	last: Position
-  end
+  end;
   SourceFile* = record
 	buffer: [1024]Char;
 	handle: ^FILE;
 	size: Word;
 	index: Word
-  end
-  FILE* = record end
+  end;
+  FILE* = record end;
   StringBuffer* = record
     data: ^Byte;
     size: Word;
     capacity: Word
-  end
+  end;
   SourceCode = record
     position: Position;
 
@@ -91,7 +91,7 @@ type
 	empty: proc(^Byte) -> Bool;
 	advance: proc(^Byte);
 	head: proc(^Byte) -> Char
-  end
+  end;
   Token* = record
     kind: Int;
     value: union
@@ -101,12 +101,12 @@ type
 	  char_value: Char
     end;
 	location: Location
-  end
+  end;
   CommandLine* = record
     input: ^Char;
 	tokenize: Bool;
 	syntax_tree: Bool
-  end
+  end;
 
 (*
   External procedures.
@@ -171,7 +171,7 @@ proc write_i(value: Int);
 var
   digit: Int;
   n: Word;
-  buffer: [10]Char
+  buffer: [10]Char;
 begin
   n := 10u;
 
@@ -228,7 +228,7 @@ end
 
 proc string_dup(origin: String) -> String;
 var
-  copy: ^Char
+  copy: ^Char;
 begin
   copy := cast(malloc(origin.length): ^Char);
   strncpy(copy, origin.ptr, origin.length);
@@ -238,7 +238,7 @@ end
 
 proc string_buffer_new() -> StringBuffer;
 var
-  result: StringBuffer
+  result: StringBuffer;
 begin
   result.capacity := 64u;
   result.data := malloc(result.capacity);
@@ -264,7 +264,7 @@ end
 
 proc string_buffer_clear(buffer: ^StringBuffer) -> String;
 var
-  result: String
+  result: String;
 begin
   result := String(cast(buffer^.data: ^Char), buffer^.size);
   buffer^.size := 0u;
@@ -283,7 +283,7 @@ end
 proc read_source(filename: ^Char) -> ^SourceFile;
 var
   result: ^SourceFile;
-  file_handle: ^FILE
+  file_handle: ^FILE;
 begin
   file_handle := fopen(filename, "rb\0".ptr);
 
@@ -298,7 +298,7 @@ end
 
 proc escape_char(escape: Char, result: ^Char) -> Bool;
 var
-  successful: Bool
+  successful: Bool;
 begin
   if escape = 'n' then
 	result^ := '\n';
@@ -344,7 +344,7 @@ end
 
 proc source_file_empty(source_input: ^Byte) -> Bool;
 var
-  source_file: ^SourceFile
+  source_file: ^SourceFile;
 begin
   source_file := cast(source_input: ^SourceFile);
 
@@ -358,7 +358,7 @@ end
 
 proc source_file_head(source_input: ^Byte) -> Char;
 var
-  source_file: ^SourceFile
+  source_file: ^SourceFile;
 begin
   source_file := cast(source_input: ^SourceFile);
 
@@ -367,7 +367,7 @@ end
 
 proc source_file_advance(source_input: ^Byte);
 var
-  source_file: ^SourceFile
+  source_file: ^SourceFile;
 begin
   source_file := cast(source_input: ^SourceFile);
 
@@ -418,7 +418,7 @@ end
 
 proc lex_identifier(source_code: ^SourceCode, token_content: ^StringBuffer);
 var
-  content_length: Word
+  content_length: Word;
 begin
   while ~source_code_empty(source_code) & is_ident(source_code_head(source_code^)) do
     string_buffer_push(token_content, source_code_head(source_code^));
@@ -428,7 +428,7 @@ end
 
 proc lex_comment(source_code: ^SourceCode, token_content: ^StringBuffer) -> Bool;
 var
-  trailing: Word
+  trailing: Word;
 begin
   trailing := 0u;
 
@@ -451,7 +451,7 @@ end
 
 proc lex_character(source_code: ^SourceCode, token_content: ^Char) -> Bool;
 var
-  successful: Bool
+  successful: Bool;
 begin
   successful := ~source_code_empty(source_code);
 
@@ -476,7 +476,7 @@ var
   token_end, constructed_string: ^Char;
   token_length: Word;
   is_valid: Bool;
-  next_char: Char
+  next_char: Char;
 begin
   is_valid := true;
 
@@ -510,7 +510,7 @@ end
 proc print_tokens(tokens: ^Token, tokens_size: Word);
 var
   current_token: ^Token;
-  i: Word
+  i: Word;
 begin
   i := 0u;
   while i < tokens_size do
@@ -658,7 +658,7 @@ end
 
 proc categorize_identifier(token_content: String) -> Token;
 var
-  current_token: Token
+  current_token: Token;
 begin
   if "if" = token_content then
 	current_token.kind := TOKEN_IF
@@ -730,7 +730,7 @@ proc tokenize(source_code: SourceCode, tokens_size: ^Word) -> ^Token;
 var
   tokens, current_token: ^Token;
   first_char: Char;
-  token_buffer: StringBuffer
+  token_buffer: StringBuffer;
 begin
   tokens_size^ := 0u;
   tokens := nil;
@@ -907,7 +907,7 @@ proc parse_command_line*(argc: Int, argv: ^^Char) -> ^CommandLine;
 var
   parameter: ^^Char;
   i: Int;
-  result: ^CommandLine
+  result: ^CommandLine;
 begin
   i := 1;
   result := cast(malloc(#size(CommandLine)): ^CommandLine);
@@ -950,7 +950,7 @@ var
   tokens_size: Word;
   source_code: SourceCode;
   command_line: ^CommandLine;
-  return_code: Int
+  return_code: Int;
 begin
   return_code := 0;