unsafe
This commit is contained in:
parent
e0277a8807
commit
a222b3807e
7 changed files with 355 additions and 110 deletions
|
|
@ -81,6 +81,8 @@ struct ParsedFile {
|
|||
nodes: Vec<ASTNode>,
|
||||
/// Hash of the file content at parse time
|
||||
content_hash: u64,
|
||||
/// Whether this file is in unsafe mode
|
||||
is_unsafe: bool,
|
||||
}
|
||||
|
||||
/// Tracks global symbols and their definitions
|
||||
|
|
@ -124,6 +126,8 @@ pub struct ImportResolver {
|
|||
processing_stack: HashSet<String>,
|
||||
/// Dependency graph: file -> list of files it depends on
|
||||
dependency_graph: HashMap<String, HashSet<String>>,
|
||||
/// Whether any file in the current compilation is unsafe
|
||||
has_unsafe_files: bool,
|
||||
}
|
||||
|
||||
impl ImportResolver {
|
||||
|
|
@ -133,6 +137,7 @@ impl ImportResolver {
|
|||
symbol_registry: GlobalSymbolRegistry::default(),
|
||||
processing_stack: HashSet::new(),
|
||||
dependency_graph: HashMap::new(),
|
||||
has_unsafe_files: false,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -191,6 +196,7 @@ impl ImportResolver {
|
|||
})?;
|
||||
|
||||
let content_hash = Self::hash_content(&source);
|
||||
let is_unsafe = source.trim_start().starts_with("# UNSAFE");
|
||||
|
||||
// Check if we have a valid cached version
|
||||
if let Some(cached) = self.parse_cache.get(filename) {
|
||||
|
|
@ -211,6 +217,7 @@ impl ImportResolver {
|
|||
ParsedFile {
|
||||
nodes: nodes.clone(),
|
||||
content_hash,
|
||||
is_unsafe,
|
||||
},
|
||||
);
|
||||
|
||||
|
|
@ -295,6 +302,13 @@ impl ImportResolver {
|
|||
let nodes = self.parse_file(filename)?;
|
||||
let mut result = Vec::new();
|
||||
|
||||
// Check if this file is unsafe
|
||||
if let Some(cached) = self.parse_cache.get(filename) {
|
||||
if cached.is_unsafe {
|
||||
self.has_unsafe_files = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Collect dependencies
|
||||
let deps = self.collect_dependencies(filename, &nodes);
|
||||
self.dependency_graph
|
||||
|
|
@ -393,10 +407,23 @@ impl ImportResolver {
|
|||
Ok(result)
|
||||
}
|
||||
|
||||
/// Check if the current compilation contains any unsafe files
|
||||
pub fn has_unsafe_files(&self) -> bool {
|
||||
self.has_unsafe_files
|
||||
}
|
||||
|
||||
/// Resolve all imports starting from the given file
|
||||
pub fn resolve(&mut self, filename: &str) -> Result<Vec<ASTNode>, ImportError> {
|
||||
println!("Starting import resolution...");
|
||||
self.resolve_imports_recursive(filename)
|
||||
self.has_unsafe_files = false; // Reset for new compilation
|
||||
let result = self.resolve_imports_recursive(filename);
|
||||
// Check if the main file is unsafe
|
||||
if let Ok(source) = fs::read_to_string(filename) {
|
||||
if source.trim_start().starts_with("# UNSAFE") {
|
||||
self.has_unsafe_files = true;
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
315
src/main.rs
315
src/main.rs
|
|
@ -1,13 +1,103 @@
|
|||
use clap::Parser;
|
||||
use std::fs;
|
||||
use suicmez::{
|
||||
ast::*,
|
||||
codegen::transpiler::Transpiler,
|
||||
import_resolver::ImportResolver,
|
||||
lambda_lower::LambdaLowerer,
|
||||
monomorphize::{Monomorphizer, check_no_typevars},
|
||||
typechecker::TypeChecker,
|
||||
typechecker::{Type, TypeChecker},
|
||||
};
|
||||
|
||||
/// Convert ASTNode to TypedASTNode for unsafe mode (with dummy types)
|
||||
fn convert_to_typed_ast(nodes: &[ASTNode]) -> Vec<TypedASTNode> {
|
||||
nodes.iter().map(|node| {
|
||||
let dummy_type = Type::Unit; // Use unit type as dummy
|
||||
let dummy_expr = TypedExpr {
|
||||
kind: TypedExprKind::Int(0), // dummy expression
|
||||
span: Span::new(&(0..0), "dummy".to_string()),
|
||||
attributes: vec![],
|
||||
ty: dummy_type.clone(),
|
||||
};
|
||||
|
||||
let kind = match &node.kind {
|
||||
ASTNodeKind::Function(f) => TypedASTNodeKind::Function(TypedFunction {
|
||||
name: f.name.clone(),
|
||||
parameters: f.parameters.clone(),
|
||||
args: f.args.iter().map(|(name, typ)| {
|
||||
(BindingId(0), name.clone(), typ.clone()) // dummy binding id
|
||||
}).collect(),
|
||||
return_type: f.return_type.clone(),
|
||||
body: dummy_expr.clone(),
|
||||
ty: dummy_type.clone(),
|
||||
}),
|
||||
ASTNodeKind::Const(c) => TypedASTNodeKind::Const(TypedConst {
|
||||
name: c.name.clone(),
|
||||
typ: c.typ.clone(),
|
||||
value: dummy_expr.clone(),
|
||||
}),
|
||||
ASTNodeKind::Struct(s) => TypedASTNodeKind::Struct(TypedStruct {
|
||||
name: s.name.clone(),
|
||||
parameters: s.parameters.clone(),
|
||||
fields: s.fields.iter().map(|f| TypedField {
|
||||
name: f.name.clone(),
|
||||
field_type: f.field_type.clone(),
|
||||
span: f.span.clone(),
|
||||
}).collect(),
|
||||
}),
|
||||
ASTNodeKind::Enum(e) => TypedASTNodeKind::Enum(TypedEnum {
|
||||
name: e.name.clone(),
|
||||
parameters: e.parameters.clone(),
|
||||
variants: e.variants.iter().map(|v| TypedVariant {
|
||||
name: v.name.clone(),
|
||||
fields: v.fields.clone(),
|
||||
span: v.span.clone(),
|
||||
}).collect(),
|
||||
}),
|
||||
ASTNodeKind::Impl(i) => TypedASTNodeKind::Impl(TypedImpl {
|
||||
target: i.target.clone(),
|
||||
trait_name: i.trait_name.clone(),
|
||||
methods: i.methods.iter().map(|m| TypedFunction {
|
||||
name: m.name.clone(),
|
||||
parameters: m.parameters.clone(),
|
||||
args: m.args.iter().map(|(name, typ)| {
|
||||
(BindingId(0), name.clone(), typ.clone())
|
||||
}).collect(),
|
||||
return_type: m.return_type.clone(),
|
||||
body: dummy_expr.clone(),
|
||||
ty: dummy_type.clone(),
|
||||
}).collect(),
|
||||
}),
|
||||
ASTNodeKind::Trait(t) => TypedASTNodeKind::Trait(TypedTrait {
|
||||
name: t.name.clone(),
|
||||
methods: t.methods.clone(),
|
||||
parameters: t.parameters.clone(),
|
||||
associated_types: vec![],
|
||||
}),
|
||||
ASTNodeKind::Extern(e) => TypedASTNodeKind::Extern(TypedExtern {
|
||||
name: e.name.clone(),
|
||||
args: e.args.clone(),
|
||||
return_type: e.return_type.clone(),
|
||||
from: e.from.clone(),
|
||||
span: e.span.clone(),
|
||||
}),
|
||||
ASTNodeKind::Load(l) => TypedASTNodeKind::Load(TypedLoad {
|
||||
library: l.library.clone(),
|
||||
alias: l.alias.clone(),
|
||||
span: l.span.clone(),
|
||||
}),
|
||||
ASTNodeKind::Use(u) => TypedASTNodeKind::Use(u.clone()),
|
||||
};
|
||||
|
||||
TypedASTNode {
|
||||
kind,
|
||||
span: node.span.clone(),
|
||||
attributes: node.attributes.clone(),
|
||||
ty: dummy_type,
|
||||
}
|
||||
}).collect()
|
||||
}
|
||||
|
||||
#[derive(Parser)]
|
||||
#[command(author, version, about = "A compiler for the Sui language")]
|
||||
struct Args {
|
||||
|
|
@ -206,6 +296,8 @@ fn run_file(filename: &str, debug: bool) -> Result<(), String> {
|
|||
}
|
||||
})?;
|
||||
|
||||
let is_unsafe = resolver.has_unsafe_files();
|
||||
|
||||
println!(
|
||||
"Import resolution complete! {} total nodes loaded",
|
||||
ast_nodes.len()
|
||||
|
|
@ -226,59 +318,126 @@ fn run_file(filename: &str, debug: bool) -> Result<(), String> {
|
|||
lowered_nodes.len()
|
||||
);
|
||||
|
||||
// Typecheck the AST
|
||||
let mut typechecker = TypeChecker::new();
|
||||
let typed_nodes = typechecker
|
||||
.typecheck_program(&lowered_nodes)
|
||||
.map_err(|e| format_type_error(&source, &e))?;
|
||||
let typed_nodes = if is_unsafe {
|
||||
println!("Unsafe mode detected - skipping type checking");
|
||||
// Convert AST nodes to typed nodes with dummy types
|
||||
convert_to_typed_ast(&lowered_nodes)
|
||||
} else {
|
||||
// Typecheck the AST
|
||||
let mut typechecker = TypeChecker::new();
|
||||
typechecker
|
||||
.typecheck_program(&lowered_nodes)
|
||||
.map_err(|e| format_type_error(&source, &e))?
|
||||
};
|
||||
|
||||
println!(
|
||||
"Type checking passed! {} nodes typechecked.",
|
||||
typed_nodes.len()
|
||||
);
|
||||
if is_unsafe {
|
||||
println!("Unsafe mode - skipping monomorphization and type variable checks");
|
||||
} else {
|
||||
println!(
|
||||
"Type checking passed! {} nodes typechecked.",
|
||||
typed_nodes.len()
|
||||
);
|
||||
|
||||
// Debug: show typed nodes
|
||||
println!("\nTyped AST nodes before monomorphization:");
|
||||
for (i, node) in typed_nodes.iter().enumerate() {
|
||||
let node_type = match &node.kind {
|
||||
suicmez::ast::TypedASTNodeKind::Function(f) => {
|
||||
format!("Function({})", f.name)
|
||||
}
|
||||
suicmez::ast::TypedASTNodeKind::Const(c) => {
|
||||
format!("Const({})", c.name)
|
||||
}
|
||||
suicmez::ast::TypedASTNodeKind::Struct(s) => {
|
||||
format!("Struct({}) with {} params", s.name, s.parameters.len())
|
||||
}
|
||||
suicmez::ast::TypedASTNodeKind::Enum(e) => {
|
||||
format!("Enum({}) with {} params", e.name, e.parameters.len())
|
||||
}
|
||||
suicmez::ast::TypedASTNodeKind::Impl(imp) => {
|
||||
format!("Impl({})", imp.target)
|
||||
}
|
||||
suicmez::ast::TypedASTNodeKind::Trait(t) => {
|
||||
format!("Trait({})", t.name)
|
||||
}
|
||||
suicmez::ast::TypedASTNodeKind::Extern(e) => {
|
||||
format!("Extern({})", e.name)
|
||||
}
|
||||
suicmez::ast::TypedASTNodeKind::Load(l) => {
|
||||
format!("Load({})", l.alias)
|
||||
}
|
||||
suicmez::ast::TypedASTNodeKind::Use(u) => {
|
||||
format!("Use({})", u.path)
|
||||
}
|
||||
};
|
||||
println!(" [{}] {}", i, node_type);
|
||||
// Debug: show typed nodes
|
||||
println!("\nTyped AST nodes before monomorphization:");
|
||||
for (i, node) in typed_nodes.iter().enumerate() {
|
||||
let node_type = match &node.kind {
|
||||
suicmez::ast::TypedASTNodeKind::Function(f) => {
|
||||
format!("Function({})", f.name)
|
||||
}
|
||||
suicmez::ast::TypedASTNodeKind::Const(c) => {
|
||||
format!("Const({})", c.name)
|
||||
}
|
||||
suicmez::ast::TypedASTNodeKind::Struct(s) => {
|
||||
format!("Struct({}) with {} params", s.name, s.parameters.len())
|
||||
}
|
||||
suicmez::ast::TypedASTNodeKind::Enum(e) => {
|
||||
format!("Enum({}) with {} params", e.name, e.parameters.len())
|
||||
}
|
||||
suicmez::ast::TypedASTNodeKind::Impl(imp) => {
|
||||
format!("Impl({})", imp.target)
|
||||
}
|
||||
suicmez::ast::TypedASTNodeKind::Trait(t) => {
|
||||
format!("Trait({})", t.name)
|
||||
}
|
||||
suicmez::ast::TypedASTNodeKind::Extern(e) => {
|
||||
format!("Extern({})", e.name)
|
||||
}
|
||||
suicmez::ast::TypedASTNodeKind::Load(l) => {
|
||||
format!("Load({})", l.alias)
|
||||
}
|
||||
suicmez::ast::TypedASTNodeKind::Use(u) => {
|
||||
format!("Use({})", u.path)
|
||||
}
|
||||
};
|
||||
println!(" [{}] {}", i, node_type);
|
||||
}
|
||||
}
|
||||
|
||||
// Monomorphize the AST
|
||||
let monomorphizer = Monomorphizer::new();
|
||||
let mono_nodes = monomorphizer
|
||||
.monomorphize_program(&typed_nodes)
|
||||
.map_err(|e| {
|
||||
let final_nodes = if is_unsafe {
|
||||
// Skip monomorphization for unsafe mode
|
||||
typed_nodes
|
||||
} else {
|
||||
// Monomorphize the AST
|
||||
let monomorphizer = Monomorphizer::new();
|
||||
let mono_nodes = monomorphizer
|
||||
.monomorphize_program(&typed_nodes)
|
||||
.map_err(|e| {
|
||||
format!(
|
||||
"Monomorphization error: {}{}",
|
||||
e.message,
|
||||
if let Some(span) = &e.span {
|
||||
format!(" at {}:{}", span.file, span.start)
|
||||
} else {
|
||||
String::new()
|
||||
}
|
||||
)
|
||||
})?;
|
||||
|
||||
println!(
|
||||
"Monomorphization passed! {} nodes after specialization.",
|
||||
mono_nodes.len()
|
||||
);
|
||||
|
||||
// Print detailed info about each node
|
||||
println!("\nMonomorphized AST nodes:");
|
||||
for (i, node) in mono_nodes.iter().enumerate() {
|
||||
let node_type = match &node.kind {
|
||||
suicmez::ast::TypedASTNodeKind::Function(f) => {
|
||||
format!("Function({})", f.name)
|
||||
}
|
||||
suicmez::ast::TypedASTNodeKind::Const(c) => {
|
||||
format!("Const({})", c.name)
|
||||
}
|
||||
suicmez::ast::TypedASTNodeKind::Struct(s) => {
|
||||
format!("Struct({}) with {} params", s.name, s.parameters.len())
|
||||
}
|
||||
suicmez::ast::TypedASTNodeKind::Enum(e) => {
|
||||
format!("Enum({}) with {} params", e.name, e.parameters.len())
|
||||
}
|
||||
suicmez::ast::TypedASTNodeKind::Impl(imp) => {
|
||||
format!("Impl({})", imp.target)
|
||||
}
|
||||
suicmez::ast::TypedASTNodeKind::Trait(t) => {
|
||||
format!("Trait({})", t.name)
|
||||
}
|
||||
suicmez::ast::TypedASTNodeKind::Extern(e) => {
|
||||
format!("Extern({})", e.name)
|
||||
}
|
||||
suicmez::ast::TypedASTNodeKind::Load(l) => {
|
||||
format!("Load({})", l.alias)
|
||||
}
|
||||
suicmez::ast::TypedASTNodeKind::Use(u) => {
|
||||
format!("Use({})", u.path)
|
||||
}
|
||||
};
|
||||
println!(" [{}] {}", i, node_type);
|
||||
}
|
||||
|
||||
// Check that no type variables remain
|
||||
check_no_typevars(&mono_nodes).map_err(|e| {
|
||||
format!(
|
||||
"Monomorphization error: {}{}",
|
||||
"Type variable check failed: {}{}",
|
||||
e.message,
|
||||
if let Some(span) = &e.span {
|
||||
format!(" at {}:{}", span.file, span.start)
|
||||
|
|
@ -288,65 +447,15 @@ fn run_file(filename: &str, debug: bool) -> Result<(), String> {
|
|||
)
|
||||
})?;
|
||||
|
||||
println!(
|
||||
"Monomorphization passed! {} nodes after specialization.",
|
||||
mono_nodes.len()
|
||||
);
|
||||
println!("Type variable check passed! No type variables remain in AST.");
|
||||
|
||||
// Print detailed info about each node
|
||||
println!("\nMonomorphized AST nodes:");
|
||||
for (i, node) in mono_nodes.iter().enumerate() {
|
||||
let node_type = match &node.kind {
|
||||
suicmez::ast::TypedASTNodeKind::Function(f) => {
|
||||
format!("Function({})", f.name)
|
||||
}
|
||||
suicmez::ast::TypedASTNodeKind::Const(c) => {
|
||||
format!("Const({})", c.name)
|
||||
}
|
||||
suicmez::ast::TypedASTNodeKind::Struct(s) => {
|
||||
format!("Struct({}) with {} params", s.name, s.parameters.len())
|
||||
}
|
||||
suicmez::ast::TypedASTNodeKind::Enum(e) => {
|
||||
format!("Enum({}) with {} params", e.name, e.parameters.len())
|
||||
}
|
||||
suicmez::ast::TypedASTNodeKind::Impl(imp) => {
|
||||
format!("Impl({})", imp.target)
|
||||
}
|
||||
suicmez::ast::TypedASTNodeKind::Trait(t) => {
|
||||
format!("Trait({})", t.name)
|
||||
}
|
||||
suicmez::ast::TypedASTNodeKind::Extern(e) => {
|
||||
format!("Extern({})", e.name)
|
||||
}
|
||||
suicmez::ast::TypedASTNodeKind::Load(l) => {
|
||||
format!("Load({})", l.alias)
|
||||
}
|
||||
suicmez::ast::TypedASTNodeKind::Use(u) => {
|
||||
format!("Use({})", u.path)
|
||||
}
|
||||
};
|
||||
println!(" [{}] {}", i, node_type);
|
||||
}
|
||||
|
||||
// Check that no type variables remain
|
||||
check_no_typevars(&mono_nodes).map_err(|e| {
|
||||
format!(
|
||||
"Type variable check failed: {}{}",
|
||||
e.message,
|
||||
if let Some(span) = &e.span {
|
||||
format!(" at {}:{}", span.file, span.start)
|
||||
} else {
|
||||
String::new()
|
||||
}
|
||||
)
|
||||
})?;
|
||||
|
||||
println!("Type variable check passed! No type variables remain in AST.");
|
||||
mono_nodes
|
||||
};
|
||||
|
||||
// Generate C code
|
||||
let mut transpiler = Transpiler::new(debug);
|
||||
let c_code = transpiler
|
||||
.transpile_program(&mono_nodes)
|
||||
.transpile_program(&final_nodes)
|
||||
.map_err(|e| format!("Code generation error: {}", e))?;
|
||||
|
||||
// Write C code to file
|
||||
|
|
|
|||
|
|
@ -23,7 +23,28 @@ static void* suic_alloc_struct(const TypeInfo* type, size_t size, void* init_dat
|
|||
}
|
||||
|
||||
|
||||
struct Color {
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
uint8_t a;
|
||||
};
|
||||
struct Shader {
|
||||
int id;
|
||||
};
|
||||
|
||||
static const uint8_t sui_bitmap_Color[] = { 0, 0, 0, 0 };
|
||||
static const TypeInfo sui_typeinfo_Color = {
|
||||
.field_count = 4,
|
||||
.pointer_count = 0,
|
||||
.pointer_bitmap = sui_bitmap_Color
|
||||
};
|
||||
static const uint8_t sui_bitmap_Shader[] = { 0 };
|
||||
static const TypeInfo sui_typeinfo_Shader = {
|
||||
.field_count = 1,
|
||||
.pointer_count = 0,
|
||||
.pointer_bitmap = sui_bitmap_Shader
|
||||
};
|
||||
|
||||
int suic_main(void);
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,28 @@ static void* suic_alloc_struct(const TypeInfo* type, size_t size, void* init_dat
|
|||
}
|
||||
|
||||
|
||||
struct Color {
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
uint8_t a;
|
||||
};
|
||||
struct Shader {
|
||||
int id;
|
||||
};
|
||||
|
||||
static const uint8_t sui_bitmap_Color[] = { 0, 0, 0, 0 };
|
||||
static const TypeInfo sui_typeinfo_Color = {
|
||||
.field_count = 4,
|
||||
.pointer_count = 0,
|
||||
.pointer_bitmap = sui_bitmap_Color
|
||||
};
|
||||
static const uint8_t sui_bitmap_Shader[] = { 0 };
|
||||
static const TypeInfo sui_typeinfo_Shader = {
|
||||
.field_count = 1,
|
||||
.pointer_count = 0,
|
||||
.pointer_bitmap = sui_bitmap_Shader
|
||||
};
|
||||
|
||||
int suic_main(void);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#include "../libsuicmez/libsuicmez.h"
|
||||
#include "libsuicmez/libsuicmez.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
|
@ -23,13 +23,38 @@ static void* suic_alloc_struct(const TypeInfo* type, size_t size, void* init_dat
|
|||
}
|
||||
|
||||
|
||||
struct Color {
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
uint8_t a;
|
||||
};
|
||||
struct Shader {
|
||||
int id;
|
||||
};
|
||||
|
||||
static const uint8_t sui_bitmap_Color[] = { 0, 0, 0, 0 };
|
||||
static const TypeInfo sui_typeinfo_Color = {
|
||||
.field_count = 4,
|
||||
.pointer_count = 0,
|
||||
.pointer_bitmap = sui_bitmap_Color
|
||||
};
|
||||
static const uint8_t sui_bitmap_Shader[] = { 0 };
|
||||
static const TypeInfo sui_typeinfo_Shader = {
|
||||
.field_count = 1,
|
||||
.pointer_count = 0,
|
||||
.pointer_bitmap = sui_bitmap_Shader
|
||||
};
|
||||
|
||||
int suic_main(void);
|
||||
|
||||
|
||||
int suic_main(void) {
|
||||
(true ? 1 : 0);
|
||||
if (true) {
|
||||
1;
|
||||
} else {
|
||||
0;
|
||||
}
|
||||
int i = 0;
|
||||
while ((i < 5)) {
|
||||
i = (i + 1);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#include "../libsuicmez/libsuicmez.h"
|
||||
#include "libsuicmez/libsuicmez.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
|
@ -23,7 +23,28 @@ static void* suic_alloc_struct(const TypeInfo* type, size_t size, void* init_dat
|
|||
}
|
||||
|
||||
|
||||
struct Color {
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
uint8_t a;
|
||||
};
|
||||
struct Shader {
|
||||
int id;
|
||||
};
|
||||
|
||||
static const uint8_t sui_bitmap_Color[] = { 0, 0, 0, 0 };
|
||||
static const TypeInfo sui_typeinfo_Color = {
|
||||
.field_count = 4,
|
||||
.pointer_count = 0,
|
||||
.pointer_bitmap = sui_bitmap_Color
|
||||
};
|
||||
static const uint8_t sui_bitmap_Shader[] = { 0 };
|
||||
static const TypeInfo sui_typeinfo_Shader = {
|
||||
.field_count = 1,
|
||||
.pointer_count = 0,
|
||||
.pointer_bitmap = sui_bitmap_Shader
|
||||
};
|
||||
|
||||
int add(int x, int y);
|
||||
int suic_main(void);
|
||||
|
|
|
|||
|
|
@ -31,6 +31,15 @@ struct Person {
|
|||
char* name;
|
||||
int age;
|
||||
};
|
||||
struct Color {
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
uint8_t a;
|
||||
};
|
||||
struct Shader {
|
||||
int id;
|
||||
};
|
||||
|
||||
static const uint8_t sui_bitmap_Point[] = { 0, 0 };
|
||||
static const TypeInfo sui_typeinfo_Point = {
|
||||
|
|
@ -44,13 +53,25 @@ static const TypeInfo sui_typeinfo_Person = {
|
|||
.pointer_count = 1,
|
||||
.pointer_bitmap = sui_bitmap_Person
|
||||
};
|
||||
static const uint8_t sui_bitmap_Color[] = { 0, 0, 0, 0 };
|
||||
static const TypeInfo sui_typeinfo_Color = {
|
||||
.field_count = 4,
|
||||
.pointer_count = 0,
|
||||
.pointer_bitmap = sui_bitmap_Color
|
||||
};
|
||||
static const uint8_t sui_bitmap_Shader[] = { 0 };
|
||||
static const TypeInfo sui_typeinfo_Shader = {
|
||||
.field_count = 1,
|
||||
.pointer_count = 0,
|
||||
.pointer_bitmap = sui_bitmap_Shader
|
||||
};
|
||||
|
||||
int suic_main(void);
|
||||
|
||||
|
||||
int suic_main(void) {
|
||||
struct Point* p = suic_alloc_struct(&sui_typeinfo_Point, sizeof(struct Point), &(struct Point){ .x = 5, .y = 10 });
|
||||
struct Person* person = suic_alloc_struct(&sui_typeinfo_Person, sizeof(struct Person), &(struct Person){ .name = suic_alloc_array(NULL, sizeof(char), 6, "Alice"), .age = 30 });
|
||||
struct Point* p = (struct Point){ .x = 5, .y = 10 };
|
||||
struct Person* person = (struct Person){ .name = suic_alloc_array(NULL, sizeof(char), 6, "Alice"), .age = 30 };
|
||||
int _ = ((*p).x + (*person).age);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue