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: 1 addition & 1 deletion src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ pub use program::Program;
pub use map::{MapDecl, MapType, Type};
pub use unit::{
Assignment, AssignmentOp, Expr, ExprKind, HeapVarDecl,
IfGuard, MethodCall, Stmt, StmtKind, Unit, VarDecl, VarType,BinaryExpr, BinOp
IfGuard, MethodCall, Stmt, StmtKind, Unit, VarDecl, VarType,BinaryExpr, BinOp, CallExpr
};
pub use event::{EventDecl, EventField, EventType, PrimitiveType};
2 changes: 1 addition & 1 deletion src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ pub fn compile(input_path: &Path, _output_path: &Path) -> Result<(), miette::Rep
.wrap_err("Lowering failed")?;

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

Expand Down
12 changes: 11 additions & 1 deletion src/diagnostics/category.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ pub enum ErrorType {
TypeError,
/// Internal error from IR/Codegen stage
InternalError,
/// I/O error
IoError,
}

impl ErrorType {
Expand All @@ -17,6 +19,7 @@ impl ErrorType {
Self::SyntaxError => "Syntax error",
Self::TypeError => "Type error",
Self::InternalError => "Internal error",
Self::IoError => "I/O error",
}
}
}
Expand All @@ -37,6 +40,10 @@ pub enum ErrorCategory {
Semantic,
/// Errors from the code generation phase
Codegen,
/// Errors from the optimizer phase
Optimizer,
/// I/O errors
Io,
}

impl ErrorCategory {
Expand All @@ -46,6 +53,8 @@ impl ErrorCategory {
Self::Parse => "Parse",
Self::Semantic => "Semantic",
Self::Codegen => "Codegen",
Self::Optimizer => "Optimizer",
Self::Io => "I/O",
}
}

Expand All @@ -55,7 +64,8 @@ impl ErrorCategory {
Self::Lexical => ErrorType::InvalidToken,
Self::Parse => ErrorType::SyntaxError,
Self::Semantic => ErrorType::TypeError,
Self::Codegen => ErrorType::InternalError,
Self::Codegen | Self::Optimizer => ErrorType::InternalError,
Self::Io => ErrorType::IoError,
}
}
}
Expand Down
25 changes: 13 additions & 12 deletions src/diagnostics/diagnostic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,19 @@ use thiserror::Error;
#[error("{error_type}: {code}\n {message}")]
pub struct CompileDiagnostic {
#[source_code]
pub source_code: String,
pub file_content: String,

#[label("{label_message}")]
pub span: SourceSpan,

#[help]
pub file_name: String,

pub code: String,
pub category: ErrorCategory,
pub error_type: ErrorType,
pub message: String,
pub label_message: String,
}


pub struct DiagnosticBuilder {
category: ErrorCategory,
code: ErrorCode,
Expand All @@ -40,6 +38,11 @@ impl DiagnosticBuilder {
}
}

pub fn with_label(mut self, label: impl Into<String>) -> Self {
self.label_message = Some(label.into());
self
}

pub fn build(
self,
span: &Span,
Expand All @@ -50,24 +53,22 @@ impl DiagnosticBuilder {
.ok_or("File content not found")?
.to_string();

let file_name = source_manager
.file_name(span.file)
.ok_or("File name not found")?
.to_string();

let label_message = self
.label_message
.unwrap_or_else(|| String::from("error here"));

Ok(CompileDiagnostic {
source_code: file_content,
file_content,
span: span.to_source_span(),
file_name, // Include the file name
code: self.code.code(),
category: self.category,
error_type: self.category.to_error_type(),
message: self.message,
label_message,
})
}
}
}

impl CompileDiagnostic {

}
2 changes: 1 addition & 1 deletion 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, ErrorType};
pub use diagnostic::{CompileDiagnostic, DiagnosticBuilder};
pub use error_code::ErrorCode;
pub use source_manager::{FileId, Span, SourceManager};
41 changes: 36 additions & 5 deletions src/diagnostics/source_manager.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@


use std::collections::HashMap;
use std::ops::Range;

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct FileId(pub u32);


#[derive(Debug, Clone)]
pub struct Span {
pub file: FileId,
Expand All @@ -21,36 +24,64 @@ pub struct SourceManager {
}

impl SourceManager {
/// Create a new source manager
pub fn new() -> Self {
Self {
files: HashMap::new(),
next_id: 0,
}
}

/// Add a new source file and return its ID
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 });

id
}

pub fn file_content(&self, id: FileId) -> Option<&str> {
self.files.get(&id).map(|f| f.content.as_str())
/// Get a source file by ID
pub fn get(&self, id: FileId) -> Option<&SourceFile> {
self.files.get(&id)
}

/// Get the file name for a given FileId
pub fn file_name(&self, id: FileId) -> Option<&str> {
self.files.get(&id).map(|f| f.name.as_str())
}

/// Get the file content for a given FileId
pub fn file_content(&self, id: FileId) -> Option<&str> {
self.files.get(&id).map(|f| f.content.as_str())
}

/// Get line and column information for a byte offset
pub fn line_col(&self, file: FileId, byte_offset: usize) -> Option<(usize, usize)> {
let content = self.file_content(file)?;

let mut line = 1;
let mut col = 1;

for (i, ch) in content.chars().enumerate() {
if i >= byte_offset {
break;
}
if ch == '\n' {
line += 1;
col = 1;
} else {
col += 1;
}
}

Some((line, col))
}
}

impl Span {
pub fn new(file: FileId, range: Range<usize>) -> Self {
Self { file, range }
}

pub fn to_source_span(&self) -> miette::SourceSpan {
(self.range.start..self.range.end).into()
}
Expand Down
36 changes: 0 additions & 36 deletions src/emit/btf/ext.rs

This file was deleted.

65 changes: 0 additions & 65 deletions src/emit/btf/mod.rs

This file was deleted.

38 changes: 38 additions & 0 deletions src/emit/ebpf_c/cgroup.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use std::fmt::Write;
use crate::ir::UnitIr;

pub fn emit_cgroup(out: &mut String, unit: &UnitIr, section: &str) -> Result<(), String> {
emit_license(out, &unit.license)?;

writeln!(out, "SEC(\"{}\")", section).map_err(err)?;
writeln!(out, "int {}(struct __sk_buff *skb) {{", unit.name).map_err(err)?;
writeln!(out, " void *data = (void *)(long)skb->data;").map_err(err)?;
writeln!(out, " void *data_end = (void *)(long)skb->data_end;").map_err(err)?;
writeln!(out, " if (data >= data_end) return SK_DROP;").map_err(err)?;
writeln!(out, " return SK_PASS;").map_err(err)?;
writeln!(out, "}}").map_err(err)?;
writeln!(out).map_err(err)?;

Ok(())
}

pub fn emit_cgroup_sock_addr(out: &mut String, unit: &UnitIr) -> Result<(), String> {
emit_license(out, &unit.license)?;

writeln!(out, "SEC(\"cgroup/sock_addr\")").map_err(err)?;
writeln!(out, "int {}(struct bpf_sock_addr *ctx) {{", unit.name).map_err(err)?;
writeln!(out, " return 1; // allow connection").map_err(err)?;
writeln!(out, "}}").map_err(err)?;
writeln!(out).map_err(err)?;
Ok(())
}

fn emit_license(out: &mut String, lic: &str) -> Result<(), String> {
writeln!(out, "char LICENSE[] SEC(\"license\") = \"{}\";", lic).map_err(err)?;
writeln!(out).map_err(err)?;
Ok(())
}

fn err(e: std::fmt::Error) -> String {
e.to_string()
}
27 changes: 27 additions & 0 deletions src/emit/ebpf_c/fentry.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use std::fmt::Write;

use crate::ir::UnitIr;

pub fn emit_fentry(out: &mut String, unit: &UnitIr, sec: &str) -> Result<(), String> {
emit_license(out, &unit.license)?;

// sec: "fentry/<func>" or "fexit/<func>"
writeln!(out, "SEC(\"{}\")", sec).map_err(err)?;
writeln!(out, "int {}(void *ctx) {{", unit.name).map_err(err)?;
writeln!(out, " (void)ctx;").map_err(err)?;
writeln!(out, " return 0;").map_err(err)?;
writeln!(out, "}}").map_err(err)?;
writeln!(out).map_err(err)?;

Ok(())
}

fn emit_license(out: &mut String, lic: &str) -> Result<(), String> {
writeln!(out, "char LICENSE[] SEC(\"license\") = \"{}\";", lic).map_err(err)?;
writeln!(out).map_err(err)?;
Ok(())
}

fn err(e: std::fmt::Error) -> String {
e.to_string()
}
Loading