Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,7 @@ vmlinux.h

build.sh

/examples

/test
.snx
5 changes: 1 addition & 4 deletions src/ast/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,7 @@ pub enum EventType {
Bytes(u32),

/// Fixed-size integer array (e.g. u32[16])
Array {
elem: PrimitiveType,
len: u32,
},
Array { elem: PrimitiveType, len: u32 },
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
Expand Down
5 changes: 2 additions & 3 deletions src/ast/map.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

use crate::parser::SourceLoc;

#[derive(Debug, Clone)]
Expand All @@ -16,7 +15,7 @@ pub enum MapType {
Hash,
Array,
Ringbuf,
LruHash,
LruHash,
ProgArray,
}

Expand All @@ -26,4 +25,4 @@ pub enum Type {
U64,
I32,
I64,
}
}
13 changes: 6 additions & 7 deletions src/ast/mod.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@

pub mod program;
pub mod event;
pub mod map;
pub mod program;
pub mod unit;
pub mod event;

pub use program::Program;
pub use event::{EventDecl, EventField, EventType, PrimitiveType};
pub use map::{MapDecl, MapType, Type};
pub use program::Program;
pub use unit::{
Assignment, AssignmentOp, Expr, ExprKind, HeapVarDecl,
IfGuard, MethodCall, Stmt, StmtKind, Unit, VarDecl, VarType,BinaryExpr, BinOp
Assignment, AssignmentOp, BinOp, BinaryExpr, Expr, ExprKind, HeapVarDecl, IfGuard, MethodCall,
Stmt, StmtKind, Unit, VarDecl, VarType,
};
pub use event::{EventDecl, EventField, EventType, PrimitiveType};
2 changes: 1 addition & 1 deletion src/ast/program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ pub struct Program {
pub maps: Vec<MapDecl>,
pub units: Vec<Unit>,
pub events: Vec<crate::ast::EventDecl>,
}
}
Empty file removed src/build/clang.rs
Empty file.
11 changes: 0 additions & 11 deletions src/build/layout.rs

This file was deleted.

2 changes: 0 additions & 2 deletions src/build/mod.rs

This file was deleted.

32 changes: 0 additions & 32 deletions src/build/vmlinux.rs

This file was deleted.

73 changes: 37 additions & 36 deletions src/compiler.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::diagnostics::{
CompileDiagnostic, DiagnosticBuilder, ErrorCategory, ErrorCode, SourceManager, Span,
};
use crate::lexer::Lexer;
use crate::parser;
use miette::{IntoDiagnostic, Report, WrapErr};
use std::fs;
Expand Down Expand Up @@ -70,7 +71,7 @@ impl ErrorHandler {
}
}

pub fn compile(input_path: &Path, _output_path: &Path) -> Result<(), miette::Report> {
pub fn compile(input_path: &Path, output_path: &Path) -> Result<(), miette::Report> {
match input_path.extension().and_then(|e| e.to_str()) {
Some("snx") => {}
_ => {
Expand Down Expand Up @@ -101,29 +102,33 @@ pub fn compile(input_path: &Path, _output_path: &Path) -> Result<(), miette::Rep

let mut error_handler = ErrorHandler::new();
let _file_id = error_handler.add_file(input_path.display().to_string(), src.clone());
let program = match parser::parse(&src) {
Ok(prog) => prog,

let tokens = match Lexer::new(&src).tokenize() {
Ok(tokens) => tokens,
Err(e) => {
let span = Span::new(_file_id, e.0.offset..e.0.offset + 1);
let code = lexical_error_code(&e.1);

match error_handler.lexical_error(code, e.1.clone(), &span) {
Ok(diag) => {
let report = error_handler.report_error(diag);
eprintln!("{}", report);
return Err(report);
}
Err(_) => {
let report = miette::miette!("{}", e.1);
eprintln!("{}", report);
return Err(report);
}
}
}
};

let error_result = if e.1.contains("Invalid character")
|| e.1.contains("Unterminated")
|| e.1.contains("Invalid escape sequence")
|| e.1.contains("Unexpected character")
{
let code = match e.1.as_str() {
msg if msg.contains("Invalid character") => ErrorCode::InvalidCharacter,
msg if msg.contains("Unterminated comment") => ErrorCode::UnterminatedComment,
msg if msg.contains("Unterminated string") => ErrorCode::UnterminatedString,
msg if msg.contains("Invalid escape sequence") => {
ErrorCode::InvalidEscapeSequence
}
_ => ErrorCode::InvalidCharacter,
};
error_handler.lexical_error(code, e.1.clone(), &span)
} else {
error_handler.parse_error(e.1.clone(), &span)
};
let program = match parser::parse_tokens(tokens) {
Ok(prog) => prog,
Err(e) => {
let span = Span::new(_file_id, e.0.offset..e.0.offset + 1);
let error_result = error_handler.parse_error(e.1.clone(), &span);

match error_result {
Ok(diag) => {
Expand Down Expand Up @@ -297,25 +302,12 @@ pub fn compile(input_path: &Path, _output_path: &Path) -> Result<(), miette::Rep
}
}

// Build steps: prepare build dir, ensure vmlinux.h, lower and emit
let build_dir = crate::build::layout::prepare_build_dir()
.map_err(|e| miette::miette!("{}", e))
.wrap_err("Build failed")?;

crate::build::vmlinux::ensure_vmlinux(&build_dir)
.map_err(|e| miette::miette!("{}", e))
.wrap_err("Build failed")?;

let file_stem = input_path.file_stem().unwrap().to_string_lossy();

let output = build_dir.join(format!("{file_stem}.o"));

let program_ir = crate::ir::lower_program(&program)
.map_err(|e| miette::miette!("{:?}", e))
.wrap_err("Lowering failed")?;

// Emit eBPF code with stage-aware error handling
if let Err(e) = crate::emit::ebpf_c::program::emit_program(&program_ir, &output) {
// Emit native eBPF ELF object with stage-aware error handling.
if let Err(e) = crate::emit::ebpf::emit_program(&program_ir, output_path) {
let span = Span::new(_file_id, 0..1);
let error_msg = format!("Code generation failed: {}", e);

Expand All @@ -335,3 +327,12 @@ pub fn compile(input_path: &Path, _output_path: &Path) -> Result<(), miette::Rep

Ok(())
}

fn lexical_error_code(message: &str) -> ErrorCode {
match message {
msg if msg.contains("Unterminated comment") => ErrorCode::UnterminatedComment,
msg if msg.contains("Unterminated string") => ErrorCode::UnterminatedString,
msg if msg.contains("Invalid escape sequence") => ErrorCode::InvalidEscapeSequence,
_ => ErrorCode::InvalidCharacter,
}
}
4 changes: 2 additions & 2 deletions src/diagnostics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pub mod error_code;
pub mod source_manager;

// Re-export commonly used types
pub use category::{ErrorCategory};
pub use category::ErrorCategory;
pub use diagnostic::{CompileDiagnostic, DiagnosticBuilder};
pub use error_code::ErrorCode;
pub use source_manager::{FileId, Span, SourceManager};
pub use source_manager::{FileId, SourceManager, Span};
13 changes: 11 additions & 2 deletions src/diagnostics/source_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,20 @@ impl SourceManager {
pub fn add_file(&mut self, name: String, content: String) -> FileId {
let id = FileId(self.next_id);
self.next_id += 1;
self.files.insert(id, SourceFile { name, content: Arc::new(content) });
self.files.insert(
id,
SourceFile {
name,
content: Arc::new(content),
},
);
id
}

pub fn get_named_source(&self, id: FileId) -> Option<miette::NamedSource<std::sync::Arc<String>>> {
pub fn get_named_source(
&self,
id: FileId,
) -> Option<miette::NamedSource<std::sync::Arc<String>>> {
self.files
.get(&id)
.map(|f| miette::NamedSource::new(f.name.clone(), f.content.clone()))
Expand Down
Loading
Loading