diff --git a/nls/src/analyzer/common.rs b/nls/src/analyzer/common.rs index a9083359..29acefb7 100644 --- a/nls/src/analyzer/common.rs +++ b/nls/src/analyzer/common.rs @@ -1049,6 +1049,7 @@ pub struct VarDeclExpr { pub type_: Type, pub be_capture: bool, pub heap_ident: Option, + pub is_private: bool, } #[derive(Debug, Clone)] @@ -1060,6 +1061,7 @@ pub struct AstConstDef { pub symbol_id: NodeId, pub symbol_start: usize, pub symbol_end: usize, + pub is_private: bool, } #[derive(Debug, Clone)] @@ -1177,6 +1179,7 @@ pub struct TypedefStmt { pub is_tagged_union: bool, pub impl_interfaces: Vec, pub method_table: HashMap>>, // key = ident, value = ast_fndef_t + pub is_private: bool, pub symbol_start: usize, pub symbol_end: usize, diff --git a/nls/src/analyzer/semantic.rs b/nls/src/analyzer/semantic.rs index 360c37bb..37405f52 100644 --- a/nls/src/analyzer/semantic.rs +++ b/nls/src/analyzer/semantic.rs @@ -935,6 +935,7 @@ impl<'a> Semantic<'a> { symbol_start: fndef.symbol_start, symbol_end: fndef.symbol_end, symbol_id: 0, + is_private: false, }; new_params.push(Arc::new(Mutex::new(self_vardecl))); @@ -1740,6 +1741,7 @@ impl<'a> Semantic<'a> { symbol_start: start, symbol_end: end, symbol_id: 0, + is_private: false, })); Box::new(Stmt { diff --git a/nls/src/analyzer/symbol.rs b/nls/src/analyzer/symbol.rs index 130ee4cc..1dc99fee 100644 --- a/nls/src/analyzer/symbol.rs +++ b/nls/src/analyzer/symbol.rs @@ -199,6 +199,7 @@ impl SymbolTable { is_tagged_union: false, impl_interfaces: Vec::new(), method_table: HashMap::new(), + is_private: false, symbol_start: 0, symbol_end: 0, symbol_id: 0, diff --git a/nls/src/analyzer/syntax.rs b/nls/src/analyzer/syntax.rs index 6822f965..a16d884e 100644 --- a/nls/src/analyzer/syntax.rs +++ b/nls/src/analyzer/syntax.rs @@ -1473,6 +1473,7 @@ impl<'a> Syntax { impl_interfaces, method_table: HashMap::new(), symbol_id: 0, + is_private: false, }))); stmt.end = self.prev().unwrap().end; @@ -1524,6 +1525,7 @@ impl<'a> Syntax { be_capture: false, heap_ident: None, symbol_id: 0, + is_private: false, }))) } @@ -1833,6 +1835,7 @@ impl<'a> Syntax { be_capture: false, heap_ident: None, symbol_id: 0, + is_private: false, }; let catch_body = self.parser_body(true)?; @@ -2360,6 +2363,7 @@ impl<'a> Syntax { be_capture: false, symbol_id: 0, heap_ident: None, + is_private: false, }; let second = if self.consume(TokenType::Comma) { @@ -2372,6 +2376,7 @@ impl<'a> Syntax { be_capture: false, heap_ident: None, symbol_id: 0, + is_private: false, }))) } else { None @@ -2926,6 +2931,7 @@ impl<'a> Syntax { be_capture: false, heap_ident: None, symbol_id: 0, + is_private: false, }))); expr.end = self.prev().unwrap().end; expr @@ -2971,6 +2977,7 @@ impl<'a> Syntax { be_capture: false, heap_ident: None, symbol_id: 0, + is_private: false, })), self.parser_expr()?, ); @@ -3004,6 +3011,7 @@ impl<'a> Syntax { be_capture: false, heap_ident: None, symbol_id: 0, + is_private: false, })), self.parser_expr()?, ); @@ -3027,6 +3035,7 @@ impl<'a> Syntax { symbol_start: const_ident.start, symbol_end: const_ident.end, symbol_id: 0, + is_private: false, }))); Ok(stmt) @@ -3321,6 +3330,7 @@ impl<'a> Syntax { fn parser_label(&mut self) -> Result, SyntaxError> { let mut fndef = AstFnDef::default(); + let mut is_private = false; while self.is(TokenType::Label) { let token = self.must(TokenType::Label)?; @@ -3334,6 +3344,7 @@ impl<'a> Syntax { fndef.linkid = Some(literal.literal.clone()); } } else if token.literal == "local" { + is_private = true; fndef.is_private = true; } else if token.literal == "where" { if fndef.pending_where_params.is_some() { @@ -3368,14 +3379,44 @@ impl<'a> Syntax { if fndef.pending_where_params.is_some() { return Err(SyntaxError(self.peek().start, self.peek().end, "#where can only be applied to fn".to_string())); } - self.parser_typedef_stmt() + let result = self.parser_typedef_stmt()?; + if is_private { + if let AstNode::Typedef(ref typedef) = result.node { + typedef.lock().unwrap().is_private = true; + } + } + Ok(result) } else if self.is(TokenType::Fn) { self.parser_fndef_stmt(fndef) + } else if self.is(TokenType::Const) { + let result = self.parser_constdef_stmt()?; + if is_private { + if let AstNode::ConstDef(ref constdef) = result.node { + constdef.lock().unwrap().is_private = true; + } + } + Ok(result) + } else if self.is(TokenType::Var) { + let result = self.parser_var_begin_stmt()?; + if is_private { + if let AstNode::VarDef(ref var_decl, _) = result.node { + var_decl.lock().unwrap().is_private = true; + } + } + Ok(result) + } else if self.is_type_begin_stmt() { + let result = self.parser_type_begin_stmt()?; + if is_private { + if let AstNode::VarDef(ref var_decl, _) = result.node { + var_decl.lock().unwrap().is_private = true; + } + } + Ok(result) } else { Err(SyntaxError( self.peek().start, self.peek().end, - format!("the label can only be used in type alias or fn"), + format!("the label can only be applied to type, fn, const, or var"), )) } } @@ -3731,6 +3772,7 @@ impl<'a> Syntax { be_capture: false, heap_ident: None, symbol_id: 0, + is_private: false, })), call_expr.clone(), ); @@ -3807,6 +3849,7 @@ impl<'a> Syntax { be_capture: false, heap_ident: None, symbol_id: 0, + is_private: false, })); let catch_body = self.parser_body(false)?; @@ -3905,6 +3948,7 @@ impl<'a> Syntax { be_capture: false, heap_ident: None, symbol_id: 0, + is_private: false, }))); }