Skip to content

Commit

Permalink
Add field data to object::Object
Browse files Browse the repository at this point in the history
  • Loading branch information
ytausky committed Oct 17, 2020
1 parent 49c81d2 commit 778eef4
Show file tree
Hide file tree
Showing 8 changed files with 159 additions and 165 deletions.
6 changes: 5 additions & 1 deletion src/assembler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::codebase::{CodebaseError, FileCodebase, FileSystem, StdFileSystem};
use crate::diagnostics::{mk_diagnostic, Diagnostic, OutputForwarder};
use crate::link::Program;
use crate::{Config, DiagnosticsConfig, InputConfig};
use crate::object::Object;

mod keywords;
mod semantics;
Expand Down Expand Up @@ -57,7 +58,10 @@ fn try_assemble<'a>(
session.analyze_file(name.into(), None)?;

let result = Program::link(
session.builder.object,
Object {
data: session.builder.data,
metadata: session.metadata,
},
session.codebase,
session.diagnostics,
);
Expand Down
82 changes: 43 additions & 39 deletions src/assembler/session/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ use crate::diagnostics::{Diagnostics, DiagnosticsContext};
use crate::expr::Expr;
use crate::object::*;

pub(crate) struct ObjectBuilder<M: SpanSource> {
pub object: Object<M>,
state: Option<BuilderState<M::Span>>,
pub(crate) struct ObjectBuilder<S> {
pub data: Data<S>,
state: Option<BuilderState<S>>,
}

enum BuilderState<S> {
Expand All @@ -15,41 +15,41 @@ enum BuilderState<S> {
SectionPrelude(usize),
}

impl<M: Default + SpanSource> ObjectBuilder<M> {
impl<S> ObjectBuilder<S> {
pub fn new() -> Self {
ObjectBuilder {
object: Object::new(),
data: Data::new(),
state: Some(BuilderState::AnonSectionPrelude { addr: None }),
}
}
}

impl<M: SpanSource> ObjectBuilder<M> {
fn push(&mut self, fragment: Fragment<Expr<SymbolId, M::Span>>) {
impl<S> ObjectBuilder<S> {
fn push(&mut self, fragment: Fragment<Expr<SymbolId, S>>) {
self.current_section().fragments.push(fragment)
}

fn current_section(&mut self) -> &mut Section<M::Span> {
fn current_section(&mut self) -> &mut Section<S> {
match self.state.take().unwrap() {
BuilderState::AnonSectionPrelude { addr } => {
self.add_section(None);
let index = self.object.content.sections.len() - 1;
let index = self.data.content.sections.len() - 1;
self.state = Some(BuilderState::Section(index));
let section = &mut self.object.content.sections[index];
let section = &mut self.data.content.sections[index];
section.constraints.addr = addr;
section
}
BuilderState::SectionPrelude(index) | BuilderState::Section(index) => {
self.state = Some(BuilderState::Section(index));
&mut self.object.content.sections[index]
&mut self.data.content.sections[index]
}
}
}

fn add_section(&mut self, symbol: Option<UserDefId>) {
self.object
self.data
.content
.add_section(symbol, self.object.vars.alloc(), self.object.vars.alloc())
.add_section(symbol, self.data.vars.alloc(), self.data.vars.alloc())
}
}

Expand All @@ -67,9 +67,9 @@ where
expr: expr.clone(),
});

let location = self.builder.object.vars.alloc();
let location = self.builder.data.vars.alloc();
self.builder.push(Fragment::Reloc(location));
self.builder.object.content.symbols.define(
self.builder.data.content.symbols.define(
name.content().unwrap(),
UserDef::Closure(Closure { expr, location }),
);
Expand All @@ -86,13 +86,13 @@ where

fn is_non_zero(&mut self, value: Expr<SymbolId, R::Span>) -> Option<bool> {
let context = LinkageContext {
content: &self.builder.object.content,
vars: &self.builder.object.vars,
content: &self.builder.data.content,
vars: &self.builder.data.vars,
location: 0.into(),
};
let mut diagnostics = DiagnosticsContext {
codebase: &mut self.codebase,
registry: &mut self.builder.object.metadata,
registry: &mut self.metadata,
diagnostics: &mut self.diagnostics,
};
value
Expand All @@ -107,7 +107,7 @@ where

match self.builder.state.take().unwrap() {
BuilderState::SectionPrelude(index) => {
self.builder.object.content.sections[index].constraints.addr = Some(addr);
self.builder.data.content.sections[index].constraints.addr = Some(addr);
self.builder.state = Some(BuilderState::SectionPrelude(index))
}
_ => self.builder.state = Some(BuilderState::AnonSectionPrelude { addr: Some(addr) }),
Expand All @@ -118,7 +118,7 @@ where
#[cfg(test)]
self.log_event(Event::StartSection { name, span: _span });

let index = self.builder.object.content.sections.len();
let index = self.builder.data.content.sections.len();
self.builder.state = Some(BuilderState::SectionPrelude(index));
self.builder.add_section(Some(name.content().unwrap()))
}
Expand All @@ -129,7 +129,7 @@ where
R: SpanSystem<BufId>,
{
fn alloc_symbol(&mut self, _: R::Span) -> SymbolId {
self.builder.object.content.symbols.alloc().into()
self.builder.data.content.symbols.alloc().into()
}
}

Expand All @@ -149,37 +149,36 @@ mod tests {

#[test]
fn new_object_has_no_sections() {
let object = build_object::<_, ()>(|_| ());
assert_eq!(object.content.sections.len(), 0)
let data = build_object::<_, ()>(|_| ());
assert_eq!(data.content.sections.len(), 0)
}

#[test]
fn no_origin_by_default() {
let object = build_object::<_, ()>(|session| session.emit_fragment(Fragment::Byte(0x00)));
assert_eq!(object.content.sections[0].constraints.addr, None)
let data = build_object::<_, ()>(|session| session.emit_fragment(Fragment::Byte(0x00)));
assert_eq!(data.content.sections[0].constraints.addr, None)
}

#[test]
fn constrain_origin_determines_origin_of_new_section() {
let origin: Expr<_, _> = 0x3000.into();
let object = build_object(|session| {
let data = build_object(|session| {
session.set_origin(origin.clone());
session.emit_fragment(Fragment::Byte(0x00))
});
assert_eq!(object.content.sections[0].constraints.addr, Some(origin))
assert_eq!(data.content.sections[0].constraints.addr, Some(origin))
}

#[test]
fn start_section_adds_named_section() {
let mut wrapped_name = None;
let object = build_object(|session| {
let data = build_object(|session| {
let name = session.alloc_symbol(());
session.start_section(name, ());
wrapped_name = Some(name);
});
assert_eq!(
object
.content
data.content
.symbols
.get(wrapped_name.unwrap().content().unwrap()),
Some(&UserDef::Section(SectionId(0)))
Expand All @@ -189,30 +188,28 @@ mod tests {
#[test]
fn set_origin_in_section_prelude_sets_origin() {
let origin: Expr<_, _> = 0x0150.into();
let object = build_object(|session| {
let data = build_object(|session| {
let name = session.alloc_symbol(());
session.start_section(name, ());
session.set_origin(origin.clone())
});
assert_eq!(object.content.sections[0].constraints.addr, Some(origin))
assert_eq!(data.content.sections[0].constraints.addr, Some(origin))
}

#[test]
fn emit_fragment_into_named_section() {
let object = build_object(|session| {
let data = build_object(|session| {
let name = session.alloc_symbol(());
session.start_section(name, ());
session.emit_fragment(Fragment::Byte(0x00))
});
assert_eq!(object.content.sections[0].fragments, [Fragment::Byte(0x00)])
assert_eq!(data.content.sections[0].fragments, [Fragment::Byte(0x00)])
}

fn build_object<F: FnOnce(&mut MockSession<S>), S: Clone + Default + Merge>(
f: F,
) -> Object<FakeSpanSystem<BufId, S>> {
fn build_object<F: FnOnce(&mut MockSession<S>), S: Clone + Default + Merge>(f: F) -> Data<S> {
let mut session = MockSession::default();
f(&mut session);
session.builder.object
session.builder.data
}

fn emit_items_and_compare<I, B>(items: I, bytes: B)
Expand Down Expand Up @@ -362,7 +359,14 @@ mod tests {
{
let diagnostics = TestDiagnosticsListener::new();
let log = diagnostics.diagnostics.clone();
let object = Program::link(build_object(f), (), diagnostics);
let object = Program::link(
Object {
data: build_object(f),
metadata: FakeSpanSystem::<(), _>::default(),
},
(),
diagnostics,
);
let diagnostics = log.into_inner().into_boxed_slice();
(object, diagnostics)
}
Expand Down
4 changes: 1 addition & 3 deletions src/assembler/session/lex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,7 @@ where
let rc_src = self.codebase.buf(buf_id);
Ok(TokenizedSrc::new(
rc_src,
self.builder
.object
.metadata
self.metadata
.add_file_inclusion(FileInclusionMetadata { file: buf_id, from }),
))
}
Expand Down
28 changes: 10 additions & 18 deletions src/assembler/session/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,11 @@ where
});

let id = MacroId(self.macros.len());
let metadata = self
.builder
.object
.metadata
.add_macro_def(MacroDefMetadata {
name_span,
param_spans,
body_spans,
});
let metadata = self.metadata.add_macro_def(MacroDefMetadata {
name_span,
param_spans,
body_spans,
});
self.macros.push(Rc::new(MacroDef {
metadata,
params,
Expand All @@ -85,15 +81,11 @@ where
});

let def = &self.macros[id];
let metadata = self
.builder
.object
.metadata
.add_macro_expansion(MacroExpansionMetadata {
def: def.metadata.clone(),
name_span,
arg_spans,
});
let metadata = self.metadata.add_macro_expansion(MacroExpansionMetadata {
def: def.metadata.clone(),
name_span,
arg_spans,
});
let expansion = MacroExpansionIter::new(metadata, Rc::clone(def), args);
self.tokens.push(Box::new(expansion));
let mut parser = <DefaultParserFactory as ParserFactory<
Expand Down
12 changes: 7 additions & 5 deletions src/assembler/session/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ where
#[cfg(test)]
log: Vec::new(),
macros: Vec::new(),
metadata: R::default(),
mnemonics,
names,
tokens: Vec::new(),
Expand Down Expand Up @@ -162,9 +163,10 @@ pub(super) struct CompositeSession<C, R: SpanSystem<BufId>, D> {
pub codebase: C,
tokens: Vec<Box<dyn TokenStream<R>>>,
macros: VecMacroTable<R::MacroDefMetadataId>,
pub metadata: R,
mnemonics: HashMap<StringRef, MnemonicEntry>,
names: BiLevelNameTable<StringRef>,
pub builder: ObjectBuilder<R>,
pub builder: ObjectBuilder<R::Span>,
pub diagnostics: D,
#[cfg(test)]
log: Vec<Event<SymbolId, MacroId, R::Span, R::Stripped>>,
Expand All @@ -186,7 +188,7 @@ impl<C, R: SpanSystem<BufId>, D> NextToken for CompositeSession<C, R, D> {
.tokens
.last_mut()
.unwrap()
.next_token(&mut self.builder.object.metadata)
.next_token(&mut self.metadata)
.unwrap();
if let Ok(Token::Sigil(Sigil::Eos)) = token.0 {
self.tokens.pop();
Expand Down Expand Up @@ -214,23 +216,23 @@ impl<C, R: SpanSystem<BufId>, D> CompositeSession<C, R, D> {
fn diagnostics(&mut self) -> DiagnosticsContext<C, R, D> {
DiagnosticsContext {
codebase: &mut self.codebase,
registry: &mut self.builder.object.metadata,
registry: &mut self.metadata,
diagnostics: &mut self.diagnostics,
}
}
}

impl<C, R: SpanSystem<BufId>, D> MergeSpans<R::Span> for CompositeSession<C, R, D> {
fn merge_spans(&mut self, left: &R::Span, right: &R::Span) -> R::Span {
self.builder.object.metadata.merge_spans(left, right)
self.metadata.merge_spans(left, right)
}
}

impl<C, R: SpanSystem<BufId>, D> StripSpan<R::Span> for CompositeSession<C, R, D> {
type Stripped = R::Stripped;

fn strip_span(&mut self, span: &R::Span) -> Self::Stripped {
self.builder.object.metadata.strip_span(span)
self.metadata.strip_span(span)
}
}

Expand Down
Loading

0 comments on commit 778eef4

Please sign in to comment.