Skip to content

Commit 7e3a678

Browse files
authored
Merge pull request #2 from Hyper66666/feat/m3-ffi-mvp
feat: FFI MVP and incremental classification hardening
2 parents b781148 + abdb800 commit 7e3a678

45 files changed

Lines changed: 3139 additions & 100 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,26 @@ Sengoo is a self-developed compiled language focused on practical engineering ou
99

1010
Sengoo is still in active development, but the CLI workflow is already usable for real local projects.
1111

12+
## AI Handoff Pack (for other LLMs)
13+
14+
To let another model take over quickly, use:
15+
16+
- `docs/AI_FEWSHOT_PLAYBOOK.md` (few-shot examples with code + why)
17+
- `sgc --error-format json ...` for machine-readable diagnostics
18+
- function contracts (`requires` / `ensures`) to encode intent before implementation
19+
- `--contract-checks auto|on|off` to decide whether runtime contract guards are inserted
20+
21+
Contract example:
22+
23+
```sg
24+
def divide(a: i64, b: i64) -> i64
25+
requires b != 0
26+
ensures result * b == a
27+
{
28+
a / b
29+
}
30+
```
31+
1232
## Practical Demos (Developer-Oriented)
1333

1434
If you want business-style proof points instead of only synthetic microbenchmarks, run:
@@ -229,9 +249,15 @@ Useful commands:
229249
# type check
230250
sgc check <file.sg>
231251

252+
# type check (JSON diagnostics for automation/agents)
253+
sgc --error-format json check <file.sg>
254+
232255
# compile and run
233256
sgc run <file.sg> -O 1
234257

258+
# compile and run with runtime contract guards (auto: on for O0/O1, off for O2/O3)
259+
sgc run <file.sg> -O 1 --contract-checks auto
260+
235261
# build native binary
236262
sgc build <file.sg> -O 2
237263

@@ -317,6 +343,26 @@ Sengoo 是一门自研编译型语言,聚焦实际工程落地:
317343

318344
项目仍在快速迭代,但本地 CLI 开发流程已经可用。
319345

346+
## AI 交接包(给其他大模型)
347+
348+
为减少上下文丢失,建议直接使用:
349+
350+
- `docs/AI_FEWSHOT_PLAYBOOK.md`(Few-shot 示例:代码 + 为什么这么写)
351+
- `sgc --error-format json ...`(机器可读编译诊断)
352+
- 契约语法 `requires` / `ensures`(先定义意图,再补实现)
353+
- `--contract-checks auto|on|off`(控制运行时是否插入契约检查)
354+
355+
契约示例:
356+
357+
```sg
358+
def divide(a: i64, b: i64) -> i64
359+
requires b != 0
360+
ensures result * b == a
361+
{
362+
a / b
363+
}
364+
```
365+
320366
## 实用 Demo(面向开发者)
321367

322368
如果你希望看到业务风格的可落地证明,而不是仅有合成微基准,可直接运行:
@@ -526,9 +572,15 @@ target/release/sgc build examples/05_loop.sg -O 2
526572
# 类型检查
527573
sgc check <file.sg>
528574

575+
# 类型检查(JSON 诊断,便于自动化/智能体)
576+
sgc --error-format json check <file.sg>
577+
529578
# 编译并运行
530579
sgc run <file.sg> -O 1
531580

581+
# 编译并运行(运行时契约检查,auto: O0/O1 开启,O2/O3 关闭)
582+
sgc run <file.sg> -O 1 --contract-checks auto
583+
532584
# 编译为原生二进制
533585
sgc build <file.sg> -O 2
534586

compiler/src/ast/decl.rs

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,11 @@ impl Decl {
7676
Self::new(DeclKind::Import(import), span)
7777
}
7878

79+
pub fn extern_block(extern_block: ExternBlock) -> Self {
80+
let span = extern_block.span;
81+
Self::new(DeclKind::ExternBlock(extern_block), span)
82+
}
83+
7984
/// 创建模块声明
8085
pub fn module(module: Module) -> Self {
8186
let span = module.span;
@@ -95,6 +100,7 @@ impl Decl {
95100
DeclKind::Const(c) => Some(&c.name),
96101
DeclKind::Static(s) => Some(&s.name),
97102
DeclKind::Import(_) => None,
103+
DeclKind::ExternBlock(_) => None,
98104
DeclKind::Module(m) => Some(&m.name),
99105
}
100106
}
@@ -112,6 +118,7 @@ impl Decl {
112118
DeclKind::Const(c) => c.vis.is_public(),
113119
DeclKind::Static(s) => s.vis.is_public(),
114120
DeclKind::Import(_) => true,
121+
DeclKind::ExternBlock(_) => true,
115122
DeclKind::Module(m) => m.vis.is_public(),
116123
}
117124
}
@@ -156,6 +163,9 @@ pub enum DeclKind {
156163
/// 导入 `import ...`
157164
Import(Import),
158165

166+
/// extern block `extern "C" { ... }`
167+
ExternBlock(ExternBlock),
168+
159169
/// 模块 `mod name { ... }`
160170
Module(Module),
161171
}
@@ -169,8 +179,14 @@ pub struct Function {
169179
pub params: Vec<Param>,
170180
pub self_param: Option<SelfParam>,
171181
pub return_type: Option<Type>,
182+
pub precondition: Option<Box<super::Expr>>,
183+
pub postcondition: Option<Box<super::Expr>>,
172184
pub body: Block,
173185
pub is_async: bool,
186+
pub abi: Option<String>,
187+
pub is_unsafe: bool,
188+
pub no_mangle: bool,
189+
pub export_name: Option<String>,
174190
pub span: Span,
175191
}
176192

@@ -183,8 +199,14 @@ impl Function {
183199
params: Vec::new(),
184200
self_param: None,
185201
return_type: None,
202+
precondition: None,
203+
postcondition: None,
186204
body,
187205
is_async: false,
206+
abi: None,
207+
is_unsafe: false,
208+
no_mangle: false,
209+
export_name: None,
188210
span,
189211
}
190212
}
@@ -226,6 +248,72 @@ impl Node for Function {
226248
}
227249
}
228250

251+
/// extern 声明块
252+
#[derive(Debug, Clone, PartialEq)]
253+
pub struct ExternBlock {
254+
pub abi: String,
255+
pub link_name: Option<String>,
256+
pub items: Vec<ExternItem>,
257+
pub span: Span,
258+
}
259+
260+
impl ExternBlock {
261+
pub fn new(abi: impl Into<String>, span: Span) -> Self {
262+
Self {
263+
abi: abi.into(),
264+
link_name: None,
265+
items: Vec::new(),
266+
span,
267+
}
268+
}
269+
}
270+
271+
impl Node for ExternBlock {
272+
fn span(&self) -> Span {
273+
self.span
274+
}
275+
}
276+
277+
/// extern 块条目
278+
#[derive(Debug, Clone, PartialEq)]
279+
pub enum ExternItem {
280+
Function(ExternFunction),
281+
Static(ExternStatic),
282+
}
283+
284+
/// extern 函数声明
285+
#[derive(Debug, Clone, PartialEq)]
286+
pub struct ExternFunction {
287+
pub vis: Visibility,
288+
pub name: Ident,
289+
pub params: Vec<Param>,
290+
pub return_type: Option<Type>,
291+
pub is_unsafe: bool,
292+
pub span: Span,
293+
}
294+
295+
impl Node for ExternFunction {
296+
fn span(&self) -> Span {
297+
self.span
298+
}
299+
}
300+
301+
/// extern 静态变量声明
302+
#[derive(Debug, Clone, PartialEq)]
303+
pub struct ExternStatic {
304+
pub vis: Visibility,
305+
pub is_mut: bool,
306+
pub name: Ident,
307+
pub ty: Type,
308+
pub span: Span,
309+
}
310+
311+
impl Node for ExternStatic {
312+
fn span(&self) -> Span {
313+
self.span
314+
}
315+
}
316+
229317
/// 结构体声明
230318
#[derive(Debug, Clone, PartialEq)]
231319
pub struct Struct {

compiler/src/ast/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ mod stmt;
1010
mod ty;
1111

1212
pub use decl::{
13-
Class, ClassMember, Const, Decl, DeclKind, Enum, EnumVariant, Function, Impl, Import,
14-
ImportKind, Module, Static, Struct, StructField, Trait, TraitItem, TypeAlias, TypeParam,
15-
VariantField,
13+
Class, ClassMember, Const, Decl, DeclKind, Enum, EnumVariant, ExternBlock, ExternFunction,
14+
ExternItem, ExternStatic, Function, Impl, Import, ImportKind, Module, Static, Struct,
15+
StructField, Trait, TraitItem, TypeAlias, TypeParam, VariantField,
1616
};
1717
pub use expr::{Expr, ExprKind};
1818
pub use op::{AssignOp, BinOp, UnOp};

compiler/src/ast/ty.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ pub enum TypeKind {
110110
/// 缁犫偓閸楁洝鐭惧鍕閸?`Name` 閹?`module::Name`
111111
Path(Path),
112112

113-
/// 濞夋稑鐎风捄顖氱窞缁鐎?Name<T1, T2>
113+
/// 濞夋稑鐎风捄顖氱窞缁鐎?Name<T1, T2>
114114
PathWithArgs { path: Path, args: Vec<Type> },
115115

116116
/// 閸忓啰绮嶇猾璇茬€?`(Type1, Type2)`

compiler/src/bin/emit_ir.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
use sengoo_compiler::compile_to_ir;
2+
use std::env;
3+
use std::fs;
4+
use std::process::ExitCode;
5+
6+
fn main() -> ExitCode {
7+
let mut args = env::args().skip(1);
8+
let Some(input_path) = args.next() else {
9+
eprintln!("usage: cargo run -p sengoo-compiler --bin emit_ir -- <input.sg> <output.ll>");
10+
return ExitCode::from(2);
11+
};
12+
let Some(output_path) = args.next() else {
13+
eprintln!("usage: cargo run -p sengoo-compiler --bin emit_ir -- <input.sg> <output.ll>");
14+
return ExitCode::from(2);
15+
};
16+
if args.next().is_some() {
17+
eprintln!("error: too many arguments");
18+
return ExitCode::from(2);
19+
}
20+
21+
let source = match fs::read_to_string(&input_path) {
22+
Ok(source) => source,
23+
Err(err) => {
24+
eprintln!("failed to read `{}`: {}", input_path, err);
25+
return ExitCode::from(1);
26+
}
27+
};
28+
29+
let ir = match compile_to_ir(&source) {
30+
Ok(ir) => ir,
31+
Err(err) => {
32+
eprintln!("failed to compile `{}`: {}", input_path, err);
33+
return ExitCode::from(1);
34+
}
35+
};
36+
37+
if let Err(err) = fs::write(&output_path, ir) {
38+
eprintln!("failed to write `{}`: {}", output_path, err);
39+
return ExitCode::from(1);
40+
}
41+
42+
ExitCode::SUCCESS
43+
}

0 commit comments

Comments
 (0)