adding case checking

This commit is contained in:
Jakub Doka 2024-11-17 20:04:53 +01:00
parent fe5a8631f6
commit 95e9270fef
No known key found for this signature in database
GPG key ID: C6E9A89936B8C143
10 changed files with 112 additions and 50 deletions

File diff suppressed because one or more lines are too long

View file

@ -548,6 +548,10 @@ pub mod ty {
};)*
}
impl Builtin {
$(pub const $name: Self = Builtin($name);)*
}
impl Id {
$(pub const $name: Self = Kind::Builtin(Builtin($name)).compress();)*
}
@ -755,7 +759,8 @@ pub mod ty {
TK::Global(idx) => {
let global = &self.tys.ins.globals[idx];
let file = &self.files[global.file.index()];
f.write_str(file.ident_str(global.name))
f.write_str(file.ident_str(global.name))?;
f.write_str(" (global)")
}
TK::Slice(idx) => {
let array = self.tys.ins.slices[idx];
@ -770,7 +775,8 @@ pub mod ty {
TK::Const(idx) => {
let cnst = &self.tys.ins.consts[idx];
let file = &self.files[cnst.file.index()];
f.write_str(file.ident_str(cnst.name))
f.write_str(file.ident_str(cnst.name))?;
f.write_str(" (const)")
}
}
}
@ -806,6 +812,7 @@ struct Func {
expr: ExprRef,
sig: Option<Sig>,
is_inline: bool,
returns_type: bool,
comp_state: [CompState; 2],
}
@ -1029,12 +1036,13 @@ pub struct Types {
trait TypeParser {
fn tys(&mut self) -> &mut Types;
fn ty_display(&self, of: ty::Id) -> ty::Display;
fn on_reuse(&mut self, existing: ty::Id);
fn find_local_ty(&mut self, name: Ident) -> Option<ty::Id>;
fn eval_const(&mut self, file: Module, expr: &Expr, ty: ty::Id) -> u64;
fn eval_global(&mut self, file: Module, name: Ident, expr: &Expr) -> ty::Id;
fn infer_type(&mut self, expr: &Expr) -> ty::Id;
fn report(&self, file: Module, pos: Pos, msg: impl Display) -> ty::Id;
fn error(&self, file: Module, pos: Pos, msg: impl Display) -> ty::Id;
fn find_type(
&mut self,
@ -1061,9 +1069,9 @@ trait TypeParser {
return match id {
Ok(_) => {
debug_assert_eq!(from_file, file);
self.report(file, pos, "somehow this was not found")
self.error(file, pos, "somehow this was not found")
}
Err("main") => self.report(
Err("main") => self.error(
from_file,
pos,
format_args!(
@ -1074,13 +1082,13 @@ trait TypeParser {
),
),
Err(name) => {
self.report(from_file, pos, format_args!("undefined indentifier: {name}"))
self.error(from_file, pos, format_args!("undefined indentifier: {name}"))
}
};
};
let tys = self.tys();
if let Some(&ty) = tys.syms.get(SymKey::Decl(file, name), &tys.ins) {
let ty = if let Some(&ty) = tys.syms.get(SymKey::Decl(file, name), &tys.ins) {
ty
} else {
let (is_ct, ty) = left
@ -1107,7 +1115,22 @@ trait TypeParser {
}
tys.syms.insert(SymKey::Decl(file, name), ty, &tys.ins);
ty
};
if let Err(proper_case) = self.tys().case(ty)(f.ident_str(name)) {
self.error(
from_file,
pos,
format_args!(
"the declaration does not have conventional \
casing, expected '{proper_case}', \
because the declared type is '{}'",
self.ty_display(ty),
),
);
}
ty
};
let tys = self.tys();
@ -1250,13 +1273,14 @@ trait TypeParser {
}
let Some(args) = self.tys().pack_args(arg_base) else {
return self.report(file, pos, "function has too many argumnets");
return self.error(file, pos, "function has too many argumnets");
};
let ret = self.parse_ty(file, ret, None, files);
Some(Sig { args, ret })
},
expr: ExprRef::new(expr),
returns_type: matches!(ret, &Expr::Ident { id, .. } if ty::Builtin::try_from(id) == Ok(ty::Builtin::TYPE)),
..Default::default()
};
@ -1269,6 +1293,21 @@ trait TypeParser {
}
impl Types {
pub fn case(&self, ty: ty::Id) -> fn(&str) -> Result<(), &'static str> {
match ty.expand() {
ty::Kind::NEVER => |_| Ok(()),
ty::Kind::Enum(_)
| ty::Kind::Struct(_)
| ty::Kind::Builtin(_)
| ty::Kind::Ptr(_)
| ty::Kind::Slice(_)
| ty::Kind::Opt(_) => utils::is_pascal_case,
ty::Kind::Func(f) if self.ins.funcs[f].returns_type => utils::is_pascal_case,
ty::Kind::Func(_) | ty::Kind::Global(_) | ty::Kind::Module(_) => utils::is_snake_case,
ty::Kind::Const(_) => utils::is_screaming_case,
}
}
fn pack_args(&mut self, arg_base: usize) -> Option<ty::Tuple> {
let base = self.ins.args.len();
self.ins.args.extend(self.tmp.args.drain(arg_base..));

View file

@ -3597,7 +3597,7 @@ impl<'a> Codegen<'a> {
ret = ret.and(self.expr(stmt));
if let Some(mut id) = ret {
if id.ty != ty::Id::VOID {
self.error(
self.warn(
stmt.pos(),
fa!(
"statements need to evaluate to 'void', \
@ -4967,11 +4967,11 @@ impl<'a> Codegen<'a> {
value.ty = to;
}
//#[track_caller]
//fn warn(&self, pos: Pos, msg: impl core::fmt::Display) {
// let mut buf = self.warnings.borrow_mut();
// write!(buf, "{}", self.file().report(pos, msg)).unwrap();
//}
#[track_caller]
fn warn(&self, pos: Pos, msg: impl core::fmt::Display) {
let mut buf = self.errors.borrow_mut();
write!(buf, "(W) {}", self.file().report(pos, msg)).unwrap();
}
#[track_caller]
fn error(&self, pos: Pos, msg: impl core::fmt::Display) {
@ -4995,6 +4995,10 @@ impl TypeParser for Codegen<'_> {
self.tys
}
fn ty_display(&self, of: ty::Id) -> ty::Display {
self.ty_display(of)
}
fn eval_const(&mut self, file: Module, expr: &Expr, ret: ty::Id) -> u64 {
self.ct.activate();
let mut scope = mem::take(&mut self.ci.scope.vars);
@ -5062,7 +5066,7 @@ impl TypeParser for Codegen<'_> {
gid.into()
}
fn report(&self, file: Module, pos: Pos, msg: impl Display) -> ty::Id {
fn error(&self, file: Module, pos: Pos, msg: impl Display) -> ty::Id {
let mut buf = self.errors.borrow_mut();
write!(buf, "{}", self.files[file.index()].report(pos, msg)).unwrap();
ty::Id::NEVER

View file

@ -12,6 +12,25 @@ use {
},
};
fn decide(b: bool, name: &'static str) -> Result<(), &'static str> {
b.then_some(()).ok_or(name)
}
pub fn is_snake_case(str: &str) -> Result<(), &'static str> {
decide(str.bytes().all(|c| matches!(c, b'a'..=b'z' | b'0'..=b'9' | b'_')), "snake_case")
}
pub fn is_pascal_case(str: &str) -> Result<(), &'static str> {
decide(
str.as_bytes()[0].is_ascii_uppercase() && str.bytes().all(|c| c.is_ascii_alphanumeric()),
"PascalCase",
)
}
pub fn is_screaming_case(str: &str) -> Result<(), &'static str> {
decide(str.bytes().all(|c| matches!(c, b'A'..=b'Z' | b'0'..=b'9' | b'_')), "SCREAMING_CASE")
}
type Nid = u16;
pub union BitSet {

View file

@ -21,7 +21,7 @@ sin:
ANDI r15, r14, 255d
ITF64 r16, r14
MULI64 r15, r15, 4d
LRA r17, r0, :SIN_TABLE
LRA r17, r0, :sin_table
LI32 r18, 1086918619w
FC64T32 r16, r16, 1b
ADDI64 r14, r14, 64d

View file

@ -1,5 +1,5 @@
main:
LRA r13, r0, :SIN_TABLE
LRA r13, r0, :sin_table
LD r13, r13, 80a, 8h
CP r1, r13
JALA r0, r31, 0a

View file

@ -19,7 +19,7 @@ free:
CP r13, r2
CP r14, r3
CP r15, r4
LRA r16, r0, :FREE_SYS_CALL
LRA r16, r0, :free_sys_call
LD r16, r16, 0a, 8h
CP r2, r16
CP r3, r13
@ -49,7 +49,7 @@ main:
malloc:
CP r13, r2
CP r14, r3
LRA r15, r0, :MALLOC_SYS_CALL
LRA r15, r0, :malloc_sys_call
LD r15, r15, 0a, 8h
CP r2, r15
CP r3, r13

View file

@ -23,7 +23,7 @@ foo:
ST r33, r254, 40a, 8h
LD r1, r32, 0a, 16h
JMP :1
2: LRA r34, r0, :MAGIC
2: LRA r34, r0, :magic
LD r34, r34, 0a, 8h
JNE r34, r32, :3
ADDI64 r32, r254, 16d
@ -41,7 +41,7 @@ get:
ADDI64 r254, r254, -32d
CP r13, r3
LD r13, r13, 0a, 1h
LRA r14, r0, :MAGIC
LRA r14, r0, :magic
ANDI r13, r13, 255d
LD r14, r14, 0a, 8h
JNE r14, r13, :0

View file

@ -2,7 +2,7 @@ get_format:
ADDI64 r254, r254, -16d
LI8 r13, 1b
ADDI64 r14, r254, 0d
LRA r15, r0, :BMP
LRA r15, r0, :bmp
ST r13, r254, 0a, 1h
LD r13, r15, 0a, 8h
ST r13, r254, 8a, 8h

View file

@ -1,6 +1,6 @@
main:
ADDI64 r254, r254, -4d
LRA r13, r0, :MAGENTA
LRA r13, r0, :magenta
ADDI64 r14, r254, 0d
BMC r13, r14, 4h
LD r13, r254, 2a, 1h