Fork of daniellemaywood.uk/gleam — Wasm codegen work
2

Configure Feed

Select the types of activity you want to include in your feed.

Implement parsing for bool `assert`

+187 -23
+36 -1
compiler-core/src/ast.rs
··· 2673 2673 Assignment(Assignment<TypeT, ExpressionT>), 2674 2674 /// A `use` expression. 2675 2675 Use(Use<TypeT, ExpressionT>), 2676 + /// An boolean assertion. 2677 + Assert(Assert<ExpressionT>), 2676 2678 } 2677 2679 2678 2680 pub type UntypedUse = Use<(), UntypedExpr>; ··· 2782 2784 Statement::Expression(expression) => expression.location(), 2783 2785 Statement::Assignment(assignment) => assignment.location, 2784 2786 Statement::Use(use_) => use_.location, 2787 + Statement::Assert(assert) => assert.location, 2785 2788 } 2786 2789 } 2787 2790 ··· 2790 2793 Statement::Expression(expression) => expression.start_byte_index(), 2791 2794 Statement::Assignment(assignment) => assignment.location.start, 2792 2795 Statement::Use(use_) => use_.location.start, 2796 + Statement::Assert(assert) => assert.location.start, 2793 2797 } 2794 2798 } 2795 2799 2796 2800 pub fn is_placeholder(&self) -> bool { 2797 2801 match self { 2798 2802 Statement::Expression(expression) => expression.is_placeholder(), 2799 - Statement::Assignment(_) | Statement::Use(_) => false, 2803 + Statement::Assignment(_) | Statement::Use(_) | Statement::Assert(_) => false, 2800 2804 } 2801 2805 } 2802 2806 } ··· 2807 2811 Statement::Expression(e) => e.is_println(), 2808 2812 Statement::Assignment(_) => false, 2809 2813 Statement::Use(_) => false, 2814 + Statement::Assert(_) => false, 2810 2815 } 2811 2816 } 2812 2817 ··· 2815 2820 Statement::Expression(expression) => expression.location(), 2816 2821 Statement::Assignment(assignment) => assignment.location, 2817 2822 Statement::Use(use_) => use_.location, 2823 + Statement::Assert(assert) => assert.location, 2818 2824 } 2819 2825 } 2820 2826 ··· 2826 2832 Statement::Expression(expression) => expression.last_location(), 2827 2833 Statement::Assignment(assignment) => assignment.value.last_location(), 2828 2834 Statement::Use(use_) => use_.call.last_location(), 2835 + Statement::Assert(assert) => assert.value.last_location(), 2829 2836 } 2830 2837 } 2831 2838 ··· 2834 2841 Statement::Expression(expression) => expression.type_(), 2835 2842 Statement::Assignment(assignment) => assignment.type_(), 2836 2843 Statement::Use(_use) => _use.call.type_(), 2844 + Statement::Assert(assert) => assert.value.type_(), 2837 2845 } 2838 2846 } 2839 2847 ··· 2842 2850 Statement::Expression(expression) => expression.definition_location(), 2843 2851 Statement::Assignment(_) => None, 2844 2852 Statement::Use(use_) => use_.call.definition_location(), 2853 + Statement::Assert(_) => None, 2845 2854 } 2846 2855 } 2847 2856 ··· 2856 2865 None 2857 2866 } 2858 2867 }), 2868 + Statement::Assert(assert) => assert.find_node(byte_index), 2859 2869 } 2860 2870 } 2861 2871 ··· 2872 2882 } 2873 2883 }) 2874 2884 } 2885 + Statement::Assert(assert) => assert.value.find_statement(byte_index).or_else(|| { 2886 + if assert.location.contains(byte_index) { 2887 + Some(self) 2888 + } else { 2889 + None 2890 + } 2891 + }), 2875 2892 } 2876 2893 } 2877 2894 ··· 2880 2897 Statement::Expression(expression) => expression.type_defining_location(), 2881 2898 Statement::Assignment(assignment) => assignment.location, 2882 2899 Statement::Use(use_) => use_.location, 2900 + Statement::Assert(assert) => assert.location, 2883 2901 } 2884 2902 } 2885 2903 ··· 2892 2910 !assignment.kind.is_assert() && assignment.value.is_pure_value_constructor() 2893 2911 } 2894 2912 Statement::Use(Use { call, .. }) => call.is_pure_value_constructor(), 2913 + // Assert statements by definition are not pure 2914 + Statement::Assert(_) => false, 2895 2915 } 2896 2916 } 2897 2917 } ··· 2922 2942 2923 2943 pub fn type_(&self) -> Arc<Type> { 2924 2944 self.value.type_() 2945 + } 2946 + } 2947 + 2948 + pub type TypedAssert = Assert<TypedExpr>; 2949 + pub type UntypedAssert = Assert<UntypedExpr>; 2950 + 2951 + #[derive(Debug, Clone, PartialEq, Eq)] 2952 + pub struct Assert<Expression> { 2953 + pub location: SrcSpan, 2954 + pub value: Expression, 2955 + } 2956 + 2957 + impl TypedAssert { 2958 + pub fn find_node(&self, byte_index: u32) -> Option<Located<'_>> { 2959 + self.value.find_node(byte_index) 2925 2960 } 2926 2961 } 2927 2962
+1 -1
compiler-core/src/ast/tests.rs
··· 59 59 fn get_bare_expression(statement: &TypedStatement) -> &TypedExpr { 60 60 match statement { 61 61 Statement::Expression(expression) => expression, 62 - Statement::Use(_) | Statement::Assignment(_) => { 62 + Statement::Use(_) | Statement::Assignment(_) | Statement::Assert(_) => { 63 63 panic!("Expected expression, got {statement:?}") 64 64 } 65 65 }
+13 -1
compiler-core/src/ast/visit.rs
··· 55 55 56 56 use super::{ 57 57 AssignName, BinOp, BitArrayOption, CallArg, Definition, Pattern, PipelineAssignmentKind, 58 - SrcSpan, Statement, TodoKind, TypeAst, TypedArg, TypedAssignment, TypedClause, 58 + SrcSpan, Statement, TodoKind, TypeAst, TypedArg, TypedAssert, TypedAssignment, TypedClause, 59 59 TypedClauseGuard, TypedConstant, TypedCustomType, TypedDefinition, TypedExpr, 60 60 TypedExprBitArraySegment, TypedFunction, TypedModule, TypedModuleConstant, TypedPattern, 61 61 TypedPatternBitArraySegment, TypedPipelineAssignment, TypedStatement, TypedUse, ··· 328 328 329 329 fn visit_typed_use(&mut self, use_: &'ast TypedUse) { 330 330 visit_typed_use(self, use_); 331 + } 332 + 333 + fn visit_typed_assert(&mut self, assert: &'ast TypedAssert) { 334 + visit_typed_assert(self, assert); 331 335 } 332 336 333 337 fn visit_typed_pipeline_assignment(&mut self, assignment: &'ast TypedPipelineAssignment) { ··· 1154 1158 Statement::Expression(expr) => v.visit_typed_expr(expr), 1155 1159 Statement::Assignment(assignment) => v.visit_typed_assignment(assignment), 1156 1160 Statement::Use(use_) => v.visit_typed_use(use_), 1161 + Statement::Assert(assert) => v.visit_typed_assert(assert), 1157 1162 } 1158 1163 } 1159 1164 ··· 1171 1176 { 1172 1177 v.visit_typed_expr(&use_.call); 1173 1178 // TODO: We should also visit the typed patterns!! 1179 + } 1180 + 1181 + pub fn visit_typed_assert<'a, V>(v: &mut V, assert: &'a TypedAssert) 1182 + where 1183 + V: Visit<'a> + ?Sized, 1184 + { 1185 + v.visit_typed_expr(&assert.value); 1174 1186 } 1175 1187 1176 1188 pub fn visit_typed_call_arg<'a, V>(v: &mut V, arg: &'a TypedCallArg)
+18 -7
compiler-core/src/ast_folder.rs
··· 5 5 use crate::{ 6 6 analyse::Inferred, 7 7 ast::{ 8 - AssignName, Assignment, BinOp, CallArg, Constant, Definition, FunctionLiteralKind, Pattern, 9 - RecordBeingUpdated, SrcSpan, Statement, TargetedDefinition, TodoKind, TypeAst, 8 + Assert, AssignName, Assignment, BinOp, CallArg, Constant, Definition, FunctionLiteralKind, 9 + Pattern, RecordBeingUpdated, SrcSpan, Statement, TargetedDefinition, TodoKind, TypeAst, 10 10 TypeAstConstructor, TypeAstFn, TypeAstHole, TypeAstTuple, TypeAstVar, UntypedArg, 11 - UntypedAssignment, UntypedClause, UntypedConstant, UntypedConstantBitArraySegment, 12 - UntypedCustomType, UntypedDefinition, UntypedExpr, UntypedExprBitArraySegment, 13 - UntypedFunction, UntypedImport, UntypedModule, UntypedModuleConstant, UntypedPattern, 14 - UntypedPatternBitArraySegment, UntypedRecordUpdateArg, UntypedStatement, UntypedTypeAlias, 15 - UntypedUse, UntypedUseAssignment, Use, UseAssignment, 11 + UntypedAssert, UntypedAssignment, UntypedClause, UntypedConstant, 12 + UntypedConstantBitArraySegment, UntypedCustomType, UntypedDefinition, UntypedExpr, 13 + UntypedExprBitArraySegment, UntypedFunction, UntypedImport, UntypedModule, 14 + UntypedModuleConstant, UntypedPattern, UntypedPatternBitArraySegment, 15 + UntypedRecordUpdateArg, UntypedStatement, UntypedTypeAlias, UntypedUse, 16 + UntypedUseAssignment, Use, UseAssignment, 16 17 }, 17 18 build::Target, 18 19 type_::error::VariableOrigin, ··· 609 610 Statement::Assignment(self.fold_assignment(assignment)) 610 611 } 611 612 Statement::Use(use_) => Statement::Use(self.fold_use(use_)), 613 + Statement::Assert(assert) => Statement::Assert(self.fold_assert(assert)), 612 614 } 613 615 } 614 616 ··· 659 661 call, 660 662 assignments, 661 663 }) 664 + } 665 + 666 + Statement::Assert(Assert { location, value }) => { 667 + let value = self.fold_expr(value); 668 + Statement::Assert(Assert { location, value }) 662 669 } 663 670 } 664 671 } ··· 885 892 886 893 fn fold_use(&mut self, use_: UntypedUse) -> UntypedUse { 887 894 use_ 895 + } 896 + 897 + fn fold_assert(&mut self, assert: UntypedAssert) -> UntypedAssert { 898 + assert 888 899 } 889 900 } 890 901
+3
compiler-core/src/call_graph.rs
··· 157 157 self.pattern(&assignment.pattern); 158 158 } 159 159 } 160 + Statement::Assert(assert) => { 161 + self.expression(&assert.value); 162 + } 160 163 }; 161 164 } 162 165
+1
compiler-core/src/erlang.rs
··· 889 889 Statement::Expression(e) => expr(e, env), 890 890 Statement::Assignment(a) => assignment(a, env), 891 891 Statement::Use(use_) => expr(&use_.call, env), 892 + Statement::Assert(_) => todo!(), 892 893 } 893 894 } 894 895
+1
compiler-core/src/format.rs
··· 2544 2544 Statement::Expression(expression) => self.expr(expression), 2545 2545 Statement::Assignment(assignment) => self.assignment(assignment), 2546 2546 Statement::Use(use_) => self.use_(use_), 2547 + Statement::Assert(_) => todo!(), 2547 2548 } 2548 2549 } 2549 2550
+5 -1
compiler-core/src/javascript/expression.rs
··· 209 209 let expression_doc = match statement { 210 210 Statement::Expression(expression) => self.expression(expression), 211 211 Statement::Assignment(assignment) => self.assignment(assignment), 212 - Statement::Use(_use) => self.expression(&_use.call), 212 + Statement::Use(use_) => self.expression(&use_.call), 213 + Statement::Assert(_) => todo!(), 213 214 }?; 214 215 Ok(self.add_statement_level(expression_doc)) 215 216 } ··· 709 710 }, 710 711 711 712 Statement::Use(use_) => return self.child_expression(&use_.call), 713 + 714 + Statement::Assert(_) => todo!(), 712 715 } 713 716 } 714 717 ··· 2040 2043 2041 2044 Statement::Assignment(_) => false, 2042 2045 Statement::Use(_) => false, 2046 + Statement::Assert(_) => false, 2043 2047 } 2044 2048 } 2045 2049
+1 -1
compiler-core/src/language_server/code_action.rs
··· 2685 2685 2686 2686 fn turn_statement_into_use(statement: &TypedStatement) -> Option<CallLocations> { 2687 2687 match statement { 2688 - ast::Statement::Use(_) | ast::Statement::Assignment(_) => None, 2688 + ast::Statement::Use(_) | ast::Statement::Assignment(_) | ast::Statement::Assert(_) => None, 2689 2689 ast::Statement::Expression(expression) => turn_expression_into_use(expression), 2690 2690 } 2691 2691 }
+25 -8
compiler-core/src/parse.rs
··· 57 57 use crate::Warning; 58 58 use crate::analyse::Inferred; 59 59 use crate::ast::{ 60 - Arg, ArgNames, AssignName, Assignment, AssignmentKind, BinOp, BitArrayOption, BitArraySegment, 61 - CAPTURE_VARIABLE, CallArg, Clause, ClauseGuard, Constant, CustomType, Definition, Function, 62 - FunctionLiteralKind, HasLocation, Import, Module, ModuleConstant, Pattern, Publicity, 63 - RecordBeingUpdated, RecordConstructor, RecordConstructorArg, SrcSpan, Statement, 64 - TargetedDefinition, TodoKind, TypeAlias, TypeAst, TypeAstConstructor, TypeAstFn, TypeAstHole, 65 - TypeAstTuple, TypeAstVar, UnqualifiedImport, UntypedArg, UntypedClause, UntypedClauseGuard, 66 - UntypedConstant, UntypedDefinition, UntypedExpr, UntypedModule, UntypedPattern, 67 - UntypedRecordUpdateArg, UntypedStatement, UntypedUseAssignment, Use, UseAssignment, 60 + Arg, ArgNames, Assert, AssignName, Assignment, AssignmentKind, BinOp, BitArrayOption, 61 + BitArraySegment, CAPTURE_VARIABLE, CallArg, Clause, ClauseGuard, Constant, CustomType, 62 + Definition, Function, FunctionLiteralKind, HasLocation, Import, Module, ModuleConstant, 63 + Pattern, Publicity, RecordBeingUpdated, RecordConstructor, RecordConstructorArg, SrcSpan, 64 + Statement, TargetedDefinition, TodoKind, TypeAlias, TypeAst, TypeAstConstructor, TypeAstFn, 65 + TypeAstHole, TypeAstTuple, TypeAstVar, UnqualifiedImport, UntypedArg, UntypedClause, 66 + UntypedClauseGuard, UntypedConstant, UntypedDefinition, UntypedExpr, UntypedModule, 67 + UntypedPattern, UntypedRecordUpdateArg, UntypedStatement, UntypedUseAssignment, Use, 68 + UseAssignment, 68 69 }; 69 70 use crate::build::Target; 70 71 use crate::error::wrap; ··· 1067 1068 })) 1068 1069 } 1069 1070 1071 + // An assert statement, with `Assert` already consumed 1072 + fn parse_assert(&mut self, start: u32) -> Result<UntypedStatement, ParseError> { 1073 + let value = self.expect_expression()?; 1074 + let end = value.location().end; 1075 + 1076 + Ok(Statement::Assert(Assert { 1077 + location: SrcSpan { start, end }, 1078 + value, 1079 + })) 1080 + } 1081 + 1070 1082 // examples: 1071 1083 // expr 1072 1084 // expr expr.. ··· 1104 1116 Some((start, Token::Let, _)) => { 1105 1117 self.advance(); 1106 1118 Ok(Some(self.parse_assignment(start)?)) 1119 + } 1120 + 1121 + Some((start, Token::Assert, _)) => { 1122 + self.advance(); 1123 + Ok(Some(self.parse_assert(start)?)) 1107 1124 } 1108 1125 1109 1126 token => {
+37
compiler-core/src/parse/snapshots/gleam_core__parse__tests__assert_statement.snap
··· 1 + --- 2 + source: compiler-core/src/parse/tests.rs 3 + expression: assert 10 != 11 4 + --- 5 + [ 6 + Assert( 7 + Assert { 8 + location: SrcSpan { 9 + start: 0, 10 + end: 15, 11 + }, 12 + value: BinOp { 13 + location: SrcSpan { 14 + start: 7, 15 + end: 15, 16 + }, 17 + name: NotEq, 18 + left: Int { 19 + location: SrcSpan { 20 + start: 7, 21 + end: 9, 22 + }, 23 + value: "10", 24 + int_value: 10, 25 + }, 26 + right: Int { 27 + location: SrcSpan { 28 + start: 13, 29 + end: 15, 30 + }, 31 + value: "11", 32 + int_value: 11, 33 + }, 34 + }, 35 + }, 36 + ), 37 + ]
+16
compiler-core/src/parse/snapshots/gleam_core__parse__tests__assert_statement_followed_by_statement.snap
··· 1 + --- 2 + source: compiler-core/src/parse/tests.rs 3 + expression: assert let a = 10 4 + --- 5 + ----- SOURCE CODE 6 + assert let a = 10 7 + 8 + ----- ERROR 9 + error: Syntax error 10 + ┌─ /src/parse/error.gleam:1:8 11 + 12 + 1 │ assert let a = 10 13 + │ ^^^ I was not expecting this 14 + 15 + Found the keyword `let`, expected one of: 16 + - An expression
+13
compiler-core/src/parse/snapshots/gleam_core__parse__tests__assert_statement_without_expression.snap
··· 1 + --- 2 + source: compiler-core/src/parse/tests.rs 3 + expression: assert 4 + --- 5 + ----- SOURCE CODE 6 + assert 7 + 8 + ----- ERROR 9 + error: Syntax error 10 + ┌─ /src/parse/error.gleam:1:6 11 + 12 + 1 │ assert 13 + │ ^ The module ended unexpectedly
+15
compiler-core/src/parse/tests.rs
··· 1766 1766 fn case_expression_without_body() { 1767 1767 assert_parse!("case a"); 1768 1768 } 1769 + 1770 + #[test] 1771 + fn assert_statement() { 1772 + assert_parse!("assert 10 != 11"); 1773 + } 1774 + 1775 + #[test] 1776 + fn assert_statement_without_expression() { 1777 + assert_error!("assert"); 1778 + } 1779 + 1780 + #[test] 1781 + fn assert_statement_followed_by_statement() { 1782 + assert_error!("assert let a = 10"); 1783 + }
+2 -3
compiler-core/src/type_/expression.rs
··· 632 632 statements.push(statement); 633 633 break; // Inferring the use has consumed the rest of the exprs 634 634 } 635 - 636 635 Statement::Expression(expression) => { 637 636 let location = expression.location(); 638 637 let expression = match self.infer_or_error(expression) { ··· 651 650 } 652 651 statements.push(Statement::Expression(expression)); 653 652 } 654 - 655 653 Statement::Assignment(assignment) => { 656 654 let assignment = self.infer_assignment(assignment); 657 655 statements.push(Statement::Assignment(assignment)); 658 656 } 657 + Statement::Assert(_) => todo!(), 659 658 } 660 659 } 661 660 ··· 4211 4210 .iter() 4212 4211 .take(assignments_count) 4213 4212 .map(|statement| match statement { 4214 - Statement::Expression(_) | Statement::Use(_) => None, 4213 + Statement::Expression(_) | Statement::Use(_) | Statement::Assert(_) => None, 4215 4214 Statement::Assignment(assignment) => Some(UseAssignment { 4216 4215 location: assignment.location, 4217 4216 pattern: assignment.pattern.clone(),