diff --git a/.vscode/launch.json b/.vscode/launch.json index 03467c2..10c407c 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,7 +1,7 @@ { "configurations": [ { - "name": "Build", + "name": "Build (std)", "type": "lldb", "request": "launch", "program": "${workspaceFolder}/dist/bin/nitro", @@ -16,7 +16,7 @@ "preLaunchTask": "build" }, { - "name": "Export", + "name": "Export (std)", "type": "lldb", "request": "launch", "program": "${workspaceFolder}/dist/bin/nitro", @@ -31,6 +31,21 @@ "RUST_BACKTRACE": "1" }, "preLaunchTask": "build" + }, + { + "name": "Build (cli)", + "type": "lldb", + "request": "launch", + "program": "${workspaceFolder}/dist/bin/nitro", + "args": [ + "build", + "${workspaceFolder}/cli" + ], + "cwd": "${workspaceFolder}", + "env": { + "RUST_BACKTRACE": "1" + }, + "preLaunchTask": "build" } ], "version": "2.0.0" diff --git a/cli/App.nt b/cli/App.nt index 8ad0858..0244fc2 100644 --- a/cli/App.nt +++ b/cli/App.nt @@ -1,6 +1,8 @@ use nitro.Int32; -class App { +class App; + +impl App { @entry fn Main(): Int32 { 0 diff --git a/stage0/src/ast/attr.rs b/stage0/src/ast/attr.rs index dad98fb..8d9deff 100644 --- a/stage0/src/ast/attr.rs +++ b/stage0/src/ast/attr.rs @@ -8,19 +8,14 @@ pub struct Attributes { condition: Option<(AttributeName, Vec)>, ext: Option<(AttributeName, Extern)>, repr: Option<(AttributeName, Representation)>, + entry: Option, customs: Vec<(AttributeName, Option>>)>, } impl Attributes { pub fn parse(lex: &mut Lexer, first: AttributeName) -> Result { // Parse the first attribute. - let mut attrs = Self { - public: None, - condition: None, - ext: None, - repr: None, - customs: Vec::new(), - }; + let mut attrs = Self::default(); attrs.parse_single(lex, first)?; @@ -34,7 +29,7 @@ impl Attributes { } None => { return Err(SyntaxError::new( - lex.last().unwrap().clone(), + lex.last().unwrap(), "expected an item after this", )); } @@ -62,11 +57,22 @@ impl Attributes { fn parse_single(&mut self, lex: &mut Lexer, name: AttributeName) -> Result<(), SyntaxError> { match name.value() { + "entry" => { + // Check for multiple entry. + if self.entry.is_some() { + return Err(SyntaxError::new( + name.span(), + "multiple entry attribute is not allowed", + )); + } + + self.entry = Some(name); + } "ext" => { // Check for multiple ext. if self.ext.is_some() { return Err(SyntaxError::new( - name.span().clone(), + name.span(), "multiple ext attribute is not allowed", )); } @@ -80,7 +86,7 @@ impl Attributes { name, match ext.value() { "C" => Extern::C, - _ => return Err(SyntaxError::new(ext.span().clone(), "unknown extern")), + _ => return Err(SyntaxError::new(ext.span(), "unknown extern")), }, )); } @@ -88,7 +94,7 @@ impl Attributes { // Check for multiple if. if self.condition.is_some() { return Err(SyntaxError::new( - name.span().clone(), + name.span(), "multiple if attribute is not allowed", )); } @@ -102,7 +108,7 @@ impl Attributes { // Check for multiple pub. if self.public.is_some() { return Err(SyntaxError::new( - name.span().clone(), + name.span(), "multiple pub attribute is not allowed", )); } @@ -124,7 +130,7 @@ impl Attributes { // Check for multiple repr. if self.repr.is_some() { return Err(SyntaxError::new( - name.span().clone(), + name.span(), "multiple repr attribute is not allowed", )); } @@ -140,18 +146,13 @@ impl Attributes { "i32" => Representation::I32, "u8" => Representation::U8, "un" => Representation::Un, - _ => { - return Err(SyntaxError::new( - repr.span().clone(), - "unknown representation", - )); - } + _ => return Err(SyntaxError::new(repr.span(), "unknown representation")), }, )); } v if v.chars().next().unwrap().is_ascii_lowercase() => { return Err(SyntaxError::new( - name.span().clone(), + name.span(), "an attribute begin with a lower case is a reserved name", )); } @@ -160,7 +161,7 @@ impl Attributes { match lex.next()? { Some(Token::OpenParenthesis(_)) => Some(Expression::parse_args(lex)?), Some(Token::CloseParenthesis(v)) => { - return Err(SyntaxError::new(v.span().clone(), "expect '('")); + return Err(SyntaxError::new(v.span(), "expect '('")); } _ => { lex.undo(); diff --git a/stage0/src/lexer/mod.rs b/stage0/src/lexer/mod.rs index 239934d..fc9bad9 100644 --- a/stage0/src/lexer/mod.rs +++ b/stage0/src/lexer/mod.rs @@ -335,9 +335,13 @@ pub struct SyntaxError { } impl SyntaxError { - pub fn new>>(span: Span, reason: R) -> Self { + pub fn new(span: S, reason: R) -> Self + where + S: Into, + R: Into>, + { Self { - span, + span: span.into(), reason: reason.into(), } } diff --git a/stage0/src/lexer/span.rs b/stage0/src/lexer/span.rs index abe7ce4..8736830 100644 --- a/stage0/src/lexer/span.rs +++ b/stage0/src/lexer/span.rs @@ -52,6 +52,12 @@ impl Span { } } +impl From<&Self> for Span { + fn from(value: &Self) -> Self { + value.clone() + } +} + impl Add for &Span { type Output = Span;