Skip to content

Commit

Permalink
fix: enforce more rules for semicolons
Browse files Browse the repository at this point in the history
  • Loading branch information
eWert-Online committed Aug 18, 2024
1 parent b24ca59 commit 018500e
Show file tree
Hide file tree
Showing 14 changed files with 142 additions and 142 deletions.
1 change: 1 addition & 0 deletions lib/02_parsing/Ast.ml
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ and statement = {
}

and statement_desc =
| CommentStatement of string
| BreakStatement of int
| ContinueStatement of int
| UseStatement of uppercase_identifier option * expression
Expand Down
71 changes: 49 additions & 22 deletions lib/02_parsing/Pinc_Parser.ml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,32 @@ let next t =
;;

let peek t =
let token = get_next_token t in
Queue.add token t.next;
let token =
match Queue.peek_opt t.next with
| None ->
let token = Lexer.scan t.lexer in
Queue.add token t.next;
token
| Some token -> token
in
token.typ
;;

let peek_2 t =
let token =
match Queue.to_seq t.next |> List.of_seq with
| [] ->
let token = Lexer.scan t.lexer in
Queue.add token t.next;
let token = Lexer.scan t.lexer in
Queue.add token t.next;
token
| [ _ ] ->
let token = Lexer.scan t.lexer in
Queue.add token t.next;
token
| _ :: token :: _ -> token
in
token.typ
;;

Expand Down Expand Up @@ -200,12 +224,20 @@ module Rules = struct
match t.token.typ with
| Token.LEFT_BRACE ->
next t;
let statements = t |> Helpers.list ~fn:parse_statement in
let rec get_statements acc =
match parse_statement t with
| Some r when optional Token.SEMICOLON t -> get_statements (r :: acc)
| Some (Ast.{ statement_desc = CommentStatement _; _ } as r) ->
get_statements (r :: acc)
| Some r -> List.rev (r :: acc)
| _ -> List.rev acc
in
let statements = get_statements [] in
t |> expect Token.RIGHT_BRACE;
Ast.BlockExpression statements |> Option.some
| _ ->
let* statement = parse_statement t in
Ast.BlockExpression [ statement ] |> Option.some
let* expr = parse_expression t in
expr.Ast.expression_desc |> Option.some
in
let expr_end = t.token.location in
let expression_loc = Location.merge ~s:expr_start ~e:expr_end () in
Expand Down Expand Up @@ -364,6 +396,10 @@ module Rules = struct
let statement_start = t.token in
let* statement_desc =
match t.token.typ with
(* PARSING COMMENT STATEMENT *)
| Token.COMMENT s ->
next t;
Some (Ast.CommentStatement s)
(* PARSING BREAK STATEMENT *)
| Token.KEYWORD_BREAK ->
next t;
Expand All @@ -374,7 +410,6 @@ module Rules = struct
i
| _ -> 1
in
let _ = optional Token.SEMICOLON t in
Some (Ast.BreakStatement num_loops)
(* PARSING CONTINUE STATEMENT *)
| Token.KEYWORD_CONTINUE ->
Expand All @@ -386,7 +421,6 @@ module Rules = struct
i
| _ -> 1
in
let _ = optional Token.SEMICOLON t in
Some (Ast.ContinueStatement num_loops)
(* PARSING LET STATEMENT *)
| Token.KEYWORD_LET -> (
Expand All @@ -398,7 +432,6 @@ module Rules = struct
t |> expect Token.EQUAL;
let end_token = t.token in
let expression = parse_expression t in
let _ = optional Token.SEMICOLON t in
match (is_mutable, is_nullable, expression) with
| false, true, Some expression ->
Some (Ast.OptionalLetStatement (Lowercase_Id identifier, expression))
Expand Down Expand Up @@ -427,7 +460,6 @@ module Rules = struct
(Location.merge ~s:start_token.location ~e:end_token.location ())
"Expected expression as right hand side of mutation statement"
in
let _ = optional Token.SEMICOLON t in
Some
(Ast.MutationStatement
(Lowercase_Id (identifier, identifier_location), expression))
Expand All @@ -446,7 +478,6 @@ module Rules = struct
t.token.location
"Expected expression as right hand side of use statement"
in
let _ = optional Token.SEMICOLON t in
Some (Ast.UseStatement (Some (Uppercase_Id identifier), expression)))
else (
let expression =
Expand All @@ -457,7 +488,6 @@ module Rules = struct
t.token.location
"Expected to see a library next to the use keyword."
in
let _ = optional Token.SEMICOLON t in
Some (Ast.UseStatement (None, expression)))
| _ ->
let* expr = parse_expression t in
Expand Down Expand Up @@ -496,16 +526,14 @@ module Rules = struct
expr |> Option.map (fun expr -> expr.Ast.expression_desc)
(* PARSING RECORD or BLOCK EXPRESSION *)
| Token.LEFT_BRACE ->
next t;
let is_record =
match t.token.typ with
| Token.IDENT_LOWER _ ->
let token = peek t in
token = Token.COLON || token = Token.QUESTIONMARK
| Token.RIGHT_BRACE -> true
match (peek t, peek_2 t) with
| Token.IDENT_LOWER _, (Token.COLON | Token.QUESTIONMARK) -> true
| Token.RIGHT_BRACE, _ -> true
| _ -> false
in
if is_record then (
next t;
let attrs =
t
|> Helpers.separated_list ~sep:Token.COMMA ~fn:parse_record_field
Expand All @@ -514,10 +542,9 @@ module Rules = struct
in
t |> expect Token.RIGHT_BRACE;
Ast.Record attrs |> Option.some)
else (
let statements = t |> Helpers.list ~fn:parse_statement in
t |> expect Token.RIGHT_BRACE;
Ast.BlockExpression statements |> Option.some)
else
let* expr = parse_block t in
Some expr.Ast.expression_desc
(* PARSING FOR IN EXPRESSION *)
| Token.KEYWORD_FOR -> (
next t;
Expand Down Expand Up @@ -685,7 +712,7 @@ module Rules = struct

and parse_expression ?(prio = -999) t =
let rec loop ~prio ~left t =
if optional Token.SEMICOLON t then
if t.token.typ = Token.SEMICOLON then
left
else (
match parse_binary_operator t with
Expand Down
1 change: 1 addition & 0 deletions lib/pinc_backend/Interpreter.ml
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ let rec get_uppercase_identifier_typ ~state ident =
and eval_statement ~state statement =
let result =
match statement.Ast.statement_desc with
| Ast.CommentStatement _ -> state
| Ast.LetStatement (Lowercase_Id ident, expression) ->
eval_let ~state ~ident ~is_mutable:false ~is_optional:false expression
| Ast.OptionalLetStatement (Lowercase_Id ident, expression) ->
Expand Down
72 changes: 38 additions & 34 deletions lib/pinc_backend/stdlib/Base__Array.pi
Original file line number Diff line number Diff line change
@@ -1,89 +1,90 @@
library Base__Array {
let make = fn (length) -> {
0..length
}
};

let init = fn (length, f) -> {
for (index in make(length)) {
f(index)
}
}
};

let length = fn (array) -> {
let mutable len = 0;
for (_ in array) len := len + 1;
for (_ in array) {
len := len + 1;
};
len
}
};

let first = fn (array) -> {
array[0]
}
};

let last = fn (array) -> {
let len = length(array);
if len > 0 {
array[len - 1]
}
}
};

let take_until = fn (array, condition) -> {
for (item in array) {
if(condition(item)) break;
item
}
}
};

let slice = fn (array, offset, length) -> {
for (index, item in array) {
if(index < offset) { continue };
if(index == length + offset) { break };

if(index < offset) continue;
if(index == length + offset) break;
item
}
}
};

let chunk = fn (array, size) -> {
let len = Base.Array.length(array);
let x = Base.Math.ceil(len / size);
0..x |> Base.Array.mapi(fn (index, item) -> {
Base.Array.slice(array, index * size, size)
});
}
};

let join = fn (array, sep) -> {
let mutable result = "";
for (index, item in array) {
if(index > 0) {
result := result ++ sep
}
result := result ++ item
}
result := result ++ sep;
};
result := result ++ item;
};
result
}
};

let map = fn (array, f) -> {
for (item in array) {
f(item)
}
}
};

let map_reverse = fn (array, f) -> {
for (item in reverse array) {
f(item)
}
}
};

let mapi = fn (array, f) -> {
for (index, item in array) {
f(index, item)
}
}
};

let mapi_reverse = fn (array, f) -> {
for (index, item in reverse array) {
f(index, item)
}
}
};

let partition = fn (array, condition) -> {
let len = Base.Array.length(array);
Expand All @@ -100,7 +101,7 @@ library Base__Array {
}
};
part([], [], 0)
}
};

let filter = fn (array, condition) -> {
let len = Base.Array.length(array);
Expand All @@ -116,10 +117,11 @@ library Base__Array {
}
}
};

aux([], 0)
}
};

let keep = filter
let keep = filter;

let find = fn (array, condition) -> {
let len = Base.Array.length(array);
Expand All @@ -133,8 +135,9 @@ library Base__Array {
}
}
};

aux(0)
}
};

let exists = fn (array, condition) -> {
let len = Base.Array.length(array);
Expand All @@ -150,10 +153,11 @@ library Base__Array {
false
}
};
aux(0)
}

let some = exists
aux(0);
};

let some = exists;

let for_all = fn (array, condition) -> {
let len = Base.Array.length(array);
Expand All @@ -167,7 +171,7 @@ library Base__Array {
};

aux(true, 0)
}
};

let every = for_all;

Expand Down Expand Up @@ -211,7 +215,7 @@ library Base__Array {

let nth = fn (array, index) -> {
array[index]
}
};

let sort = fn (array, f) -> {
let merge = fn (a, b) -> {
Expand All @@ -232,7 +236,7 @@ library Base__Array {
}
}
}
}
};

let len = Base.Array.length(array);
if len < 2 {
Expand All @@ -243,7 +247,7 @@ library Base__Array {
let second_half = array |> Base.Array.slice(h, len);
merge(sort(first_half, f), sort(second_half, f));
}
}
};

let unique = fn (array) -> {
let isSorted = false;
Expand All @@ -255,8 +259,8 @@ library Base__Array {
seen := seen <- value;
result := result <- value;
}
}
};

result
}
};
}
4 changes: 2 additions & 2 deletions lib/pinc_backend/stdlib/Base__Char.pi
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
library Base__Char {
let is_whitespace = fn (char) -> {
char == ' ' || char == '\012' || char == '\n' || char == '\r' || char == '\t'
}
};

let is_newline = fn (char) -> {
char == '\n' || char == '\r'
}
};
}
Loading

0 comments on commit 018500e

Please sign in to comment.