Skip to content

Commit

Permalink
Added beginnings of Resources
Browse files Browse the repository at this point in the history
  • Loading branch information
TrolledWoods committed Sep 10, 2020
1 parent bb79a6f commit 8dd9c48
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 32 deletions.
20 changes: 6 additions & 14 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@

mod prelude {
pub(crate) use crate::{
Location, CodeLoc, Error, Result, Routine, RoutineId,
Location, CodeLoc, Error, Result,
resource::{ Resource, ResourceKind, Resources, ResourceId },
operator::Operator,
lexer::{ self, Token, TokenKind },
parser::{ NodeKind, Ast, Node, Scopes, ScopeBuffer, ScopeId, ScopeMemberId, ScopeMemberKind },
Expand Down Expand Up @@ -49,19 +50,10 @@ mod parser;
mod types;
mod code_gen;
mod run;
mod resource;

use std::fmt;

// TODO: Move this into another file
pub struct Routine {
declaration: CodeLoc,
arguments: Vec<parser::ScopeMemberId>,
code: parser::Ast,
instructions: Option<(code_gen::Locals, Vec<code_gen::Instruction>)>,
}

pub type RoutineId = usize;

fn main() {
let code = std::fs::read_to_string("test.im").unwrap();

Expand All @@ -70,8 +62,8 @@ fn main() {
println!();

let mut scopes = Scopes::new();
let mut routines = Vec::new();
let ast = match parser::parse_code(&code, &mut routines, &mut scopes) {
let mut resources = Resources::new();
let ast = match parser::parse_code(&code, &mut resources, &mut scopes) {
Ok(value) => value,
Err(err) => {
print_error(&code, err);
Expand All @@ -81,7 +73,7 @@ fn main() {

let mut typer = types::AstTyper::new(&ast);
let mut types = types::Types::new();
match typer.try_type_ast(&mut types, &ast, &mut scopes) {
match typer.try_type_ast(&mut types, &ast, &mut scopes, &resources) {
Ok(()) => (),
Err(err) => {
print_error(&code, err);
Expand Down
37 changes: 22 additions & 15 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ struct Context<'a, 't> {
scopes: &'a mut Scopes,
scope: ScopeId,
tokens: &'a mut TokenStream<'t>,
routines: &'a mut Vec<Routine>,
resources: &'a mut Resources,
}

impl<'a, 't> Context<'a, 't> {
Expand All @@ -17,7 +17,7 @@ impl<'a, 't> Context<'a, 't> {
scopes: self.scopes,
scope: self.scope,
tokens: self.tokens,
routines: self.routines,
resources: self.resources,
}
}

Expand All @@ -28,7 +28,7 @@ impl<'a, 't> Context<'a, 't> {
scopes: self.scopes,
scope: sub_scope,
tokens: self.tokens,
routines: self.routines,
resources: self.resources,
}
}
}
Expand Down Expand Up @@ -97,6 +97,7 @@ pub enum NodeKind {
String(String),
EmptyLiteral,
Identifier(ScopeMemberId),
Resource(ResourceId),
FunctionDeclaration {
routine_id: usize,
},
Expand Down Expand Up @@ -283,7 +284,8 @@ fn parse_block(mut context: Context)
match context.tokens.next() {
Some(Token { kind: TokenKind::ClosingBracket('}'), .. }) => break,
Some(Token { kind: TokenKind::Semicolon, .. }) => (),
_ => return_error!(loc, "Expected ';' or '}}'"),
_ => return_error!(loc,
"Expected ';' or '}}', did you forget a semicolon or did you forget an operator?"),
}
}

Expand Down Expand Up @@ -333,24 +335,25 @@ fn parse_expression(
scopes: context.scopes,
scope: sub_scope,
tokens: context.tokens,
routines: context.routines,
resources: context.resources,
};

// Parse the function body.
parse_expression(sub_context.borrow())?;

let id = context.routines.len();
context.routines.push(Routine {
declaration: token.loc.clone(),
arguments: args,
code: ast,
instructions: None,
let id = context.resources.insert(Resource {
loc: token.get_location(),
kind: ResourceKind::Function {
arguments: args,
code: ast,
instructions: None,
}
});

return Ok(context.ast.insert_node(Node::new(
token,
context.scope,
NodeKind::FunctionDeclaration { routine_id: id }
NodeKind::Resource(id),
)));
}

Expand Down Expand Up @@ -424,7 +427,11 @@ fn parse_value(
context.tokens.next();
// TODO: Find a way to get rid of the string cloning here!
// Possibly by making TokenStream own its data
context.ast.insert_node(Node::new(token, context.scope, NodeKind::String(string.clone())))
let id = context.resources.insert(Resource {
loc: token.get_location(),
kind: ResourceKind::String(string.clone()),
});
context.ast.insert_node(Node::new(token, context.scope, NodeKind::Resource(id)))
}
TokenKind::Identifier(name) => {
context.tokens.next();
Expand Down Expand Up @@ -532,7 +539,7 @@ fn try_parse_list<'t, V>(

pub fn parse_code(
code: &str,
routines: &mut Vec<Routine>,
resources: &mut Resources,
scopes: &mut Scopes,
) -> Result<Ast> {
let (last_loc, tokens) = lexer::lex_code(code)?;
Expand All @@ -546,7 +553,7 @@ pub fn parse_code(
scopes,
scope,
tokens: &mut stream,
routines,
resources,
};
parse_expression(context)?;

Expand Down
52 changes: 52 additions & 0 deletions src/resource.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use crate::prelude::*;
use crate::code_gen;

pub type ResourceId = usize;

pub struct Resources {
pub members: Vec<Resource>,
}

impl Resources {
pub fn new() -> Self {
Self {
members: Vec::new(),
}
}

pub fn insert(&mut self, resource: Resource) -> ResourceId {
let id = self.members.len();
self.members.push(resource);
id
}

pub fn resource(&self, id: ResourceId) -> &Resource {
&self.members[id]
}

pub fn resource_mut(&mut self, id: ResourceId) -> &mut Resource {
&mut self.members[id]
}
}

pub struct Resource {
pub loc: CodeLoc,
pub kind: ResourceKind,
}

impl Location for Resource {
fn get_location(&self) -> CodeLoc {
self.loc.clone()
}
}

pub enum ResourceKind {
Function {
arguments: Vec<ScopeMemberId>,
// argument_type_defs: Vec<Ast>,
// argument_types: Vec<Option<TypeId>>,
code: Ast,
instructions: Option<(code_gen::Locals, Vec<code_gen::Instruction>)>,
},
String(String),
}
23 changes: 22 additions & 1 deletion src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,13 @@ impl AstTyper {
}
}

pub fn try_type_ast(&mut self, types: &mut Types, ast: &Ast, scopes: &mut Scopes) -> Result<()> {
pub fn try_type_ast(
&mut self,
types: &mut Types,
ast: &Ast,
scopes: &mut Scopes,
resources: &Resources,
) -> Result<()> {
while self.node_id < ast.nodes.len() {
debug_assert_eq!(self.types.len(), self.node_id);
let node = &ast.nodes[self.node_id];
Expand All @@ -121,6 +127,21 @@ impl AstTyper {
NodeKind::String(ref string) => {
todo!();
}
NodeKind::Resource(id) => {
let resource = resources.resource(id);
match resource.kind {
ResourceKind::Function { ref arguments, ref code, ref instructions } => {
let kind = TypeKind::FunctionPointer {
args: arguments.iter().map(|_| types.insert(Type::new(TypeKind::Primitive(PrimitiveKind::U64)))).collect(),
returns: types.insert(Type::new(TypeKind::Primitive(PrimitiveKind::U64))),
};
Some(types.insert(Type::new(kind)))
}
ResourceKind::String(ref string) => {
todo!("Strings do not have types yet");
}
}
}
NodeKind::EmptyLiteral => {
None
}
Expand Down
6 changes: 4 additions & 2 deletions test.im
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{:main
x := |x| x;
x(6)
x := {
x + 5
};
x + 25
}

0 comments on commit 8dd9c48

Please sign in to comment.