going insane (not working yet)

This commit is contained in:
2025-04-26 16:46:04 -04:00
parent 3bf821d6b1
commit 71598a4afa
23 changed files with 472 additions and 291 deletions
+7 -17
View File
@@ -1,13 +1,15 @@
use std::ops::{Deref, DerefMut};
use crate::common::FileID;
use super::{
MaybeParsable, Node, NodeParseResult, Parsable, ParsableWith, CompilerMsg, CompilerOutput,
CompilerMsg, CompilerOutput, MaybeParsable, Node, NodeParseResult, Parsable, ParsableWith,
TokenCursor,
};
pub struct ParserCtx<'a> {
pub cursor: TokenCursor<'a>,
pub output: CompilerOutput,
pub output: &'a mut CompilerOutput,
}
impl<'a> Deref for ParserCtx<'a> {
@@ -40,22 +42,10 @@ impl<'a> ParserCtx<'a> {
pub fn maybe_parse<T: MaybeParsable>(&mut self) -> Option<Node<T>> {
Node::maybe_parse(self)
}
}
impl<'a> From<TokenCursor<'a>> for ParserCtx<'a> {
fn from(cursor: TokenCursor<'a>) -> Self {
pub fn new(file: FileID, string: &'a str, output: &'a mut CompilerOutput) -> Self {
Self {
cursor,
output: CompilerOutput::new(),
}
}
}
impl<'a> From<&'a str> for ParserCtx<'a> {
fn from(string: &'a str) -> Self {
Self {
cursor: TokenCursor::from(string),
output: CompilerOutput::new(),
cursor: TokenCursor::from_file_str(file, string),
output,
}
}
}
+10 -8
View File
@@ -1,3 +1,5 @@
use crate::common::FileID;
use super::{
token::{CharCursor, Keyword, Symbol, Token, TokenInstance},
CompilerMsg, FilePos,
@@ -17,7 +19,7 @@ impl<'a> TokenCursor<'a> {
self.next_start = next
.as_ref()
.map(|i| i.span.end)
.unwrap_or(FilePos::start());
.unwrap_or(FilePos::start(self.file()));
std::mem::replace(&mut self.next, next)
}
pub fn expect_next(&mut self) -> Result<TokenInstance, CompilerMsg> {
@@ -78,11 +80,11 @@ impl<'a> TokenCursor<'a> {
pub fn next_start(&self) -> FilePos {
self.next_start
}
}
impl<'a> From<&'a str> for TokenCursor<'a> {
fn from(string: &'a str) -> Self {
Self::from(CharCursor::from(string))
pub fn from_file_str(id: FileID, string: &'a str) -> Self {
Self::from(CharCursor::from_file_str(id, string))
}
pub fn file(&self) -> FileID {
self.cursor.file()
}
}
@@ -90,10 +92,10 @@ impl<'a> From<CharCursor<'a>> for TokenCursor<'a> {
fn from(mut cursor: CharCursor<'a>) -> Self {
let cur = TokenInstance::parse(&mut cursor);
Self {
next_start: FilePos::start(cursor.file()),
prev_end: FilePos::start(cursor.file()),
cursor,
next: cur,
next_start: FilePos::start(),
prev_end: FilePos::start(),
}
}
}
+5
View File
@@ -0,0 +1,5 @@
use std::collections::HashSet;
#[derive(Clone, Eq, PartialEq, Hash)]
pub struct Import(pub Vec<String>);
pub type Imports = HashSet<Import>;
+20 -7
View File
@@ -1,14 +1,13 @@
use crate::{
ir::{Type, UInstruction, VarInst},
ir::{Type, UInstruction, UVar, VarInst},
parser::{PConstStatement, PStatementLike},
};
use super::{import::Import, FnLowerCtx, FnLowerable, PBlock, PStatement};
use super::{FnLowerCtx, FnLowerable, Import, PBlock, PStatement};
impl FnLowerable for PBlock {
type Output = VarInst;
fn lower(&self, ctx: &mut FnLowerCtx) -> Option<VarInst> {
ctx.program.push();
let mut last = None;
let mut statements = Vec::new();
let mut fn_nodes = Vec::new();
@@ -29,12 +28,26 @@ impl FnLowerable for PBlock {
}
}
// then lower imports
for i in &import_nodes {
if let Some(i) = i.as_ref() {
let import = Import(i.0.clone());
ctx.imports.push(import);
for i_n in &import_nodes {
if let Some(i) = i_n.as_ref() {
let name = &i.0;
let import = Import(ctx.program.path_for(name));
ctx
.imports
.entry(import)
.or_insert(ctx.program.def(name, None, i_n.origin));
// I could prevent this if someone imports something twice,
// but that doesn't seem worth it at all
ctx.program.def_searchable::<UVar>(
name.clone(),
Some(UVar {
ty: Type::Module,
}),
i_n.origin,
);
}
}
ctx.program.push();
// then lower const things
let mut structs = Vec::new();
for s in &struct_nodes {
+1 -1
View File
@@ -15,7 +15,7 @@ impl Node<PVarDef> {
None => Type::Infer,
};
Some(VarInst {
id: program.def_searchable(name, Some(UVar { ty, parent: None }), self.origin),
id: program.def_searchable(name, Some(UVar { ty }), self.origin),
span: self.origin,
})
}
+5 -8
View File
@@ -1,6 +1,6 @@
use super::{func::FnLowerCtx, FnLowerable, PExpr, UnaryOp};
use crate::{
ir::{FieldRef, Type, UData, UInstruction, VarInst},
ir::{MemberRef, Type, UData, UInstruction, VarInst},
parser::PInfixOp,
};
@@ -69,13 +69,10 @@ impl FnLowerable for PExpr {
return None;
};
let fname = ident.as_ref()?.0.clone();
ctx.temp_subvar(
Type::Placeholder,
FieldRef {
var: res1.id,
field: fname,
},
)
ctx.temp(Type::Member(MemberRef {
parent: res1.id,
name: fname,
}))
}
PInfixOp::Assign => {
let res1 = e1.lower(ctx)?;
+17 -8
View File
@@ -1,6 +1,6 @@
use super::{import::Import, CompilerMsg, CompilerOutput, FileSpan, FnLowerable, Node, PFunction};
use super::{Imports, CompilerMsg, CompilerOutput, FileSpan, FnLowerable, Node, PFunction};
use crate::{
ir::{FieldRef, FnID, Idents, Type, UFunc, UInstrInst, UInstruction, UProgram, UVar, VarInst},
ir::{MemberRef, FnID, Idents, Type, UFunc, UInstrInst, UInstruction, UProgram, UVar, VarInst},
parser,
};
@@ -8,7 +8,13 @@ impl Node<PFunction> {
pub fn lower_name(&self, p: &mut UProgram) -> Option<FnID> {
self.as_ref()?.lower_name(p)
}
pub fn lower(&self, id: FnID, p: &mut UProgram, imports: &mut Vec<Import>, output: &mut CompilerOutput) {
pub fn lower(
&self,
id: FnID,
p: &mut UProgram,
imports: &mut Imports,
output: &mut CompilerOutput,
) {
if let Some(s) = self.as_ref() {
s.lower(id, p, imports, output)
}
@@ -22,7 +28,13 @@ impl PFunction {
let id = p.def_searchable(name.to_string(), None, self.header.origin);
Some(id)
}
pub fn lower(&self, id: FnID, p: &mut UProgram, imports: &mut Vec<Import>, output: &mut CompilerOutput) {
pub fn lower(
&self,
id: FnID,
p: &mut UProgram,
imports: &mut Imports,
output: &mut CompilerOutput,
) {
let name = p.names.name(id).to_string();
p.push_name(&name);
let (args, ret) = if let Some(header) = self.header.as_ref() {
@@ -69,7 +81,7 @@ pub struct FnLowerCtx<'a> {
pub instructions: Vec<UInstrInst>,
pub output: &'a mut CompilerOutput,
pub origin: FileSpan,
pub imports: &'a mut Vec<Import>
pub imports: &'a mut Imports,
}
impl FnLowerCtx<'_> {
@@ -103,9 +115,6 @@ impl FnLowerCtx<'_> {
pub fn temp(&mut self, ty: Type) -> VarInst {
self.program.temp_var(self.origin, ty)
}
pub fn temp_subvar(&mut self, ty: Type, parent: FieldRef) -> VarInst {
self.program.temp_subvar(self.origin, ty, parent)
}
pub fn push(&mut self, i: UInstruction) {
self.push_at(i, self.origin);
}
-1
View File
@@ -1 +0,0 @@
pub struct Import(pub String);
+11 -5
View File
@@ -6,21 +6,26 @@ mod expr;
mod func;
mod struc;
mod ty;
mod import;
use super::*;
use crate::ir::{Type, UFunc, UProgram};
impl PModule {
pub fn lower(&self, name: String, p: &mut UProgram, output: &mut CompilerOutput) {
let id = p.def_searchable(name.clone(), None, self.block.origin);
pub fn lower(
&self,
name: String,
p: &mut UProgram,
imports: &mut Imports,
output: &mut CompilerOutput,
) {
let fid = p.def_searchable(name.clone(), None, self.block.origin);
p.push_name(&name);
let mut fctx = FnLowerCtx {
program: p,
instructions: Vec::new(),
output,
origin: self.block.origin,
imports: Vec::new(),
imports,
};
self.block.lower(&mut fctx);
let f = UFunc {
@@ -28,12 +33,13 @@ impl PModule {
instructions: fctx.instructions,
ret: Type::Unit,
};
p.write(id, f);
p.write(fid, f);
p.pop_name();
}
}
pub use func::FnLowerCtx;
use import::Imports;
pub trait FnLowerable {
type Output;
+2 -2
View File
@@ -1,5 +1,5 @@
use crate::{
ir::{GenericID, Type, UGeneric, UProgram, UStruct},
ir::{GenericID, StructTy, Type, UGeneric, UProgram, UStruct},
parser::PGenericDef,
};
@@ -24,7 +24,7 @@ impl PType {
Type::Generic { id }
} else if let Some(id) = ids.and_then(|ids| ids.get::<UStruct>()) {
let args = self.args.iter().map(|n| n.lower(p, output)).collect();
Type::Struct { id, args }
Type::Struct(StructTy { id, args })
} else if let Ok(num) = name.parse::<u32>() {
Type::Bits(num)
} else {
+2
View File
@@ -6,6 +6,7 @@ mod node;
mod nodes;
mod parse;
mod token;
mod import;
use crate::common::{CompilerMsg, CompilerOutput, FileSpan, FilePos};
pub use ctx::*;
@@ -14,6 +15,7 @@ pub use node::*;
pub use nodes::*;
pub use parse::*;
pub use token::*;
pub use import::*;
// idea: create generic "map" and "tuple" types which are used for function calls, tuples, struct
// creation, etc. instead of specializing at the parsing level
+1 -1
View File
@@ -133,7 +133,7 @@ impl<T: Parsable> ParsableWith for T {
impl<T: ParsableWith> Node<T> {
pub fn parse_with(ctx: &mut ParserCtx, data: T::Data) -> NodeParseResult<T> {
let start = ctx.peek().map(|t| t.span.start).unwrap_or(FilePos::start());
let start = ctx.peek().map(|t| t.span.start).unwrap_or(FilePos::start(ctx.cursor.file()));
let (inner, recover) = match T::parse(ctx, data) {
ParseResult::Ok(v) => (Some(v), false),
ParseResult::Recover(v) => (Some(v), true),
+11 -7
View File
@@ -1,14 +1,17 @@
use std::{iter::Peekable, str::Chars};
use crate::common::FileID;
use super::super::{CompilerMsg, FilePos};
pub struct CharCursor<'a> {
file: FileID,
chars: Peekable<Chars<'a>>,
next_pos: FilePos,
prev_pos: FilePos,
}
impl CharCursor<'_> {
impl<'a> CharCursor<'a> {
pub fn next(&mut self) -> Option<char> {
let res = self.peek()?;
self.advance();
@@ -54,14 +57,15 @@ impl CharCursor<'_> {
pub fn prev_pos(&self) -> FilePos {
self.prev_pos
}
}
impl<'a> From<&'a str> for CharCursor<'a> {
fn from(value: &'a str) -> Self {
pub fn from_file_str(file: FileID, value: &'a str) -> Self {
Self {
chars: value.chars().peekable(),
next_pos: FilePos::start(),
prev_pos: FilePos::start(),
next_pos: FilePos::start(file),
prev_pos: FilePos::start(file),
file,
}
}
pub fn file(&self) -> FileID {
self.file
}
}
+11 -3
View File
@@ -4,10 +4,10 @@ mod symbol;
use std::ops::Deref;
use super::FileSpan;
pub use cursor::*;
pub use keyword::*;
pub use symbol::*;
use super::FileSpan;
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum Token {
@@ -35,7 +35,11 @@ impl TokenInstance {
let end = cursor.prev_pos();
return Some(Self {
token: Token::Symbol(s),
span: FileSpan { start, end },
span: FileSpan {
start,
end,
file: cursor.file(),
},
});
}
let mut word = String::new();
@@ -54,7 +58,11 @@ impl TokenInstance {
};
Some(Self {
token,
span: FileSpan { start, end },
span: FileSpan {
start,
end,
file: cursor.file(),
},
})
}
}