Create alias HashMap in parser context

This commit is contained in:
Keith Yeung
2017-03-13 21:29:22 -07:00
committed by Jakob Stoklund Olesen
parent ce1ad37863
commit a18ad5a306

View File

@@ -5,6 +5,7 @@
// //
// ====--------------------------------------------------------------------------------------====// // ====--------------------------------------------------------------------------------------====//
use std::collections::HashMap;
use std::str::FromStr; use std::str::FromStr;
use std::{u16, u32}; use std::{u16, u32};
use std::mem; use std::mem;
@@ -83,6 +84,8 @@ pub struct Parser<'a> {
struct Context<'a> { struct Context<'a> {
function: Function, function: Function,
map: SourceMap, map: SourceMap,
// Store aliases until the values can be reliably looked up.
aliases: HashMap<Value, (Value, Location)>,
// Reference to the unique_isa for things like parsing ISA-specific instruction encoding // Reference to the unique_isa for things like parsing ISA-specific instruction encoding
// information. This is only `Some` if exactly one set of `isa` directives were found in the // information. This is only `Some` if exactly one set of `isa` directives were found in the
@@ -96,6 +99,7 @@ impl<'a> Context<'a> {
Context { Context {
function: f, function: f,
map: SourceMap::new(), map: SourceMap::new(),
aliases: HashMap::new(),
unique_isa: unique_isa, unique_isa: unique_isa,
} }
} }
@@ -173,6 +177,13 @@ impl<'a> Context<'a> {
self.map.def_ebb(src_ebb, ebb, loc).and(Ok(ebb)) self.map.def_ebb(src_ebb, ebb, loc).and(Ok(ebb))
} }
fn add_alias(&mut self, src: Value, dest: Value, loc: Location) -> Result<()> {
match self.aliases.insert(src, (dest, loc)) {
Some((v, _)) if v != dest => err!(loc, "duplicate alias: {} -> {}", src, dest),
_ => Ok(()),
}
}
// The parser creates all instructions with Ebb and Value references using the source file // The parser creates all instructions with Ebb and Value references using the source file
// numbering. These references need to be rewritten after parsing is complete since forward // numbering. These references need to be rewritten after parsing is complete since forward
// references are allowed. // references are allowed.
@@ -1150,7 +1161,8 @@ impl<'a> Parser<'a> {
if results.len() != 1 { if results.len() != 1 {
return err!(self.loc, "wrong number of aliases"); return err!(self.loc, "wrong number of aliases");
} }
Ok(()) let dest = self.match_value("expected value alias")?;
ctx.add_alias(results[0], dest, self.loc)
} }
// Parse an instruction, append it to `ebb`. // Parse an instruction, append it to `ebb`.