mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-11-27 12:17:35 +03:00
deprecate hardcoded stubs by changing parser
This commit is contained in:
parent
5347570d97
commit
d1d5abef5b
@ -15,17 +15,13 @@
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use super::*;
|
||||
use crate::parse_ast;
|
||||
use leo_errors::{CompilerError, ParserError, Result};
|
||||
use leo_span::{source_map::FileName, symbol::with_session_globals};
|
||||
|
||||
use std::fs;
|
||||
use leo_errors::{ParserError, Result};
|
||||
|
||||
impl ParserContext<'_> {
|
||||
/// Returns a [`Program`] AST if all tokens can be consumed and represent a valid Leo program.
|
||||
pub fn parse_program(&mut self) -> Result<Program> {
|
||||
let mut imports = IndexMap::new();
|
||||
let mut stubs: IndexMap<Symbol, Stub> = IndexMap::new();
|
||||
let mut program_scopes = IndexMap::new();
|
||||
|
||||
// TODO: Remove restrictions on multiple program scopes
|
||||
@ -37,10 +33,6 @@ impl ParserContext<'_> {
|
||||
let (id, import) = self.parse_import()?;
|
||||
imports.insert(id, import);
|
||||
}
|
||||
Token::Stub => {
|
||||
let (id, stub) = self.parse_stub()?;
|
||||
stubs.insert(id, stub);
|
||||
}
|
||||
Token::Program => {
|
||||
match parsed_program_scope {
|
||||
// Only one program scope is allowed per file.
|
||||
@ -61,7 +53,7 @@ impl ParserContext<'_> {
|
||||
return Err(ParserError::missing_program_scope(self.token.span).into());
|
||||
}
|
||||
|
||||
Ok(Program { imports, stubs, program_scopes })
|
||||
Ok(Program { imports, stubs: IndexMap::new(), program_scopes })
|
||||
}
|
||||
|
||||
fn unexpected_item(token: &SpannedToken, expected: &[Token]) -> ParserError {
|
||||
@ -95,25 +87,11 @@ impl ParserContext<'_> {
|
||||
Ok((import_name.name, (Program::default(), start + end)))
|
||||
}
|
||||
|
||||
// Read the import file into string.
|
||||
// Todo: protect against cyclic imports.
|
||||
let program_string =
|
||||
fs::read_to_string(&import_file_path).map_err(|e| CompilerError::file_read_error(&import_file_path, e))?;
|
||||
/// Parses a program scope `program foo.aleo { ... }`.
|
||||
fn parse_program_scope(&mut self) -> Result<ProgramScope> {
|
||||
// Parse `program` keyword.
|
||||
let start = self.expect(&Token::Program)?;
|
||||
|
||||
// Create import file name.
|
||||
let name: FileName = FileName::Real(import_file_path);
|
||||
|
||||
// Register the source (`program_string`) in the source map.
|
||||
let prg_sf = with_session_globals(|s| s.source_map.new_source(&program_string, name));
|
||||
|
||||
// Use the parser to construct the imported abstract syntax tree (ast).
|
||||
let program_ast = parse_ast(self.handler, self.node_builder, &prg_sf.src, prg_sf.start_pos)?;
|
||||
|
||||
Ok((import_name.name, (program_ast.into_repr(), start + end)))
|
||||
}
|
||||
|
||||
/// Parses a program body `credits.aleo { ... }`
|
||||
fn parse_program_body(&mut self, start: Span) -> Result<(ProgramScope, Vec<Identifier>)> {
|
||||
// Parse the program name.
|
||||
let name = self.expect_identifier()?;
|
||||
|
||||
@ -121,7 +99,7 @@ impl ParserContext<'_> {
|
||||
self.expect(&Token::Dot)?;
|
||||
|
||||
// Otherwise throw parser error
|
||||
self.expect(&Token::Aleo).or_else(|_| Err(ParserError::invalid_network(self.token.span)))?;
|
||||
self.expect(&Token::Aleo).map_err(|_| ParserError::invalid_network(self.token.span))?;
|
||||
|
||||
// Construct the program id.
|
||||
let program_id =
|
||||
@ -135,18 +113,9 @@ impl ParserContext<'_> {
|
||||
let mut functions: Vec<(Symbol, Function)> = Vec::new();
|
||||
let mut structs: Vec<(Symbol, Struct)> = Vec::new();
|
||||
let mut mappings: Vec<(Symbol, Mapping)> = Vec::new();
|
||||
let mut imports: Vec<Identifier> = Vec::new();
|
||||
|
||||
while self.has_next() {
|
||||
match &self.token.token {
|
||||
Token::Import => {
|
||||
self.expect(&Token::Import)?;
|
||||
let import_name = self.expect_identifier()?;
|
||||
self.expect(&Token::Dot)?;
|
||||
self.expect(&Token::Aleo)?;
|
||||
self.expect(&Token::Semicolon)?;
|
||||
imports.push(import_name);
|
||||
}
|
||||
Token::Const => {
|
||||
let declaration = self.parse_const_declaration_statement()?;
|
||||
consts.push((Symbol::intern(&declaration.place.to_string()), declaration));
|
||||
@ -182,39 +151,7 @@ impl ParserContext<'_> {
|
||||
// Parse `}`.
|
||||
let end = self.expect(&Token::RightCurly)?;
|
||||
|
||||
Ok((ProgramScope { program_id, consts, functions, structs, mappings, span: start + end }, imports))
|
||||
}
|
||||
|
||||
/// Parses a stub `stub credits.aleo { ... }`.
|
||||
fn parse_stub(&mut self) -> Result<(Symbol, Stub)> {
|
||||
// Parse `stub` keyword.
|
||||
let start = self.expect(&Token::Stub)?;
|
||||
let (program_body, imports) = self.parse_program_body(start)?;
|
||||
|
||||
Ok((program_body.program_id.name.name, Stub {
|
||||
imports,
|
||||
stub_id: program_body.program_id,
|
||||
consts: program_body.consts,
|
||||
structs: program_body.structs,
|
||||
mappings: program_body.mappings,
|
||||
functions: program_body
|
||||
.functions
|
||||
.into_iter()
|
||||
.map(|(symbol, function)| (symbol, FunctionStub::from(function)))
|
||||
.collect(),
|
||||
span: program_body.span,
|
||||
}))
|
||||
}
|
||||
|
||||
/// Parses a program scope `program foo.aleo { ... }`.
|
||||
fn parse_program_scope(&mut self) -> Result<ProgramScope> {
|
||||
// Parse `program` keyword.
|
||||
let start = self.expect(&Token::Program)?;
|
||||
let (program_scope, imports) = self.parse_program_body(start)?;
|
||||
if imports.len() != 0 {
|
||||
self.emit_err(ParserError::cannot_import_inside_program_body(self.token.span));
|
||||
}
|
||||
Ok(program_scope)
|
||||
Ok(ProgramScope { program_id, consts, functions, structs, mappings, span: start + end })
|
||||
}
|
||||
|
||||
/// Returns a [`Vec<Member>`] AST node if the next tokens represent a struct member.
|
||||
@ -269,6 +206,13 @@ impl ParserContext<'_> {
|
||||
pub(super) fn parse_struct(&mut self) -> Result<(Symbol, Struct)> {
|
||||
let is_record = matches!(&self.token.token, Token::Record);
|
||||
let start = self.expect_any(&[Token::Struct, Token::Record])?;
|
||||
|
||||
// Check if using external type
|
||||
let file_type = self.look_ahead(1, |t| &t.token);
|
||||
if self.token.token == Token::Dot && (file_type == &Token::Aleo) {
|
||||
return Err(ParserError::cannot_declare_external_struct(self.token.span).into());
|
||||
}
|
||||
|
||||
let struct_name = self.expect_identifier()?;
|
||||
|
||||
self.expect(&Token::LeftCurly)?;
|
||||
|
Loading…
Reference in New Issue
Block a user