going insane (not working yet)
This commit is contained in:
+7
-17
@@ -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
@@ -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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
use std::collections::HashSet;
|
||||
|
||||
#[derive(Clone, Eq, PartialEq, Hash)]
|
||||
pub struct Import(pub Vec<String>);
|
||||
pub type Imports = HashSet<Import>;
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -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)?;
|
||||
|
||||
@@ -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 +0,0 @@
|
||||
pub struct Import(pub String);
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(),
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user