Skip to content

Commit

Permalink
Introduce dedicated TypeExpression types, big Statement parsing refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
VonTum committed Aug 11, 2023
1 parent 31758eb commit d18d935
Show file tree
Hide file tree
Showing 8 changed files with 319 additions and 190 deletions.
21 changes: 21 additions & 0 deletions multiply_add.sus
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,27 @@ module multiply_add2 : int a, int b, int c -> int r {
}


module parallel_mul_add_att : int a, int b -> int p, int q {
int a2 = a * a;
int b2 = b + b;
@
int a3 = a * a2;
int b3 = b + b2;
@
p = a3 * a;
q = b3 + b;
@ //?
}
module parallel_mul_add_reg : int a, int b -> int p, int q {
reg int a2 = a * a;
reg int a3 = a * a2 + 3;
reg p = a * a3;

reg int b2 = b + b;
reg int b3 = b + b2;
reg q = b + b3;
}

/* a module to test the syntax */
module MultiplyAdd : i32 a, i32 b, i32 c -> i32 result {
//module beelqzd
Expand Down
122 changes: 93 additions & 29 deletions src/ast.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@

use num_bigint::BigUint;

use crate::tokenizer::{TokenTypeIdx, TokenExtraInfo};
use crate::{tokenizer::{TokenTypeIdx, TokenExtraInfo}, errors::{ParsingError, error_basic_str}};
use core::ops::Range;

use std::collections::HashMap;

// Token span. Indices are INCLUSIVE
#[derive(Clone,Copy,Debug,PartialEq,Eq)]
pub struct Span(pub usize, pub usize);
Expand Down Expand Up @@ -93,6 +95,13 @@ impl IdentifierIdx {
None
}
}
pub fn get_global(&self) -> Option<TokenExtraInfo> {
if self.name_idx >= GLOBAL_IDENTIFIER_OFFSET {
Some((self.name_idx - GLOBAL_IDENTIFIER_OFFSET) as TokenExtraInfo)
} else {
None
}
}
}

#[derive(Debug, Clone, Copy)]
Expand All @@ -101,10 +110,19 @@ pub struct IdentifierToken {
pub name_idx : TokenExtraInfo
}


#[derive(Debug, Clone)]
pub enum TypeExpression {
Named(usize),
Array(Box<(SpanTypeExpression, SpanExpression)>)
}

pub type SpanTypeExpression = (TypeExpression, Span);

#[derive(Debug,Clone)]
pub struct SignalDeclaration {
pub span : Span,
pub typ : SpanExpression,
pub typ : SpanTypeExpression,
pub name_idx : TokenExtraInfo,
pub identifier_type : IdentifierType
}
Expand All @@ -126,7 +144,7 @@ pub enum Expression {
Constant(Value),
UnaryOp(Box<(Operator, usize/*Operator token */, SpanExpression)>),
BinOp(Box<(SpanExpression, Operator, usize/*Operator token */, SpanExpression)>),
Array(Vec<SpanExpression>), // first[second, third, ...]
Array(Box<(SpanExpression, SpanExpression)>), // first[second]
FuncCall(Vec<SpanExpression>) // first(second, third, ...)
}

Expand All @@ -139,12 +157,12 @@ impl Expression {
pub type SpanExpression = (Expression, Span);
pub type SpanStatement = (Statement, Span);

pub type SpanAssignableExpression = SpanExpression;

#[derive(Debug)]
pub enum Statement {
Assign(SpanExpression, SpanExpression, usize/* Eq sign token */), // v = expr;
Mention(SpanExpression),
Assign(Vec<SpanAssignableExpression>, SpanExpression), // v = expr;
Block(Vec<SpanStatement>),
PipelineStage(usize),
TimelineStage(usize)
}

Expand All @@ -161,25 +179,53 @@ pub struct ASTRoot {
pub modules : Vec<Module>
}

pub fn for_each_identifier_in_expression<F>((expr, span) : &SpanExpression, func : &mut F) where F: FnMut(IdentifierIdx, usize) -> () {
match expr {
Expression::Named(id) => {
assert!(span.0 == span.1);
func(*id, span.0)
},
Expression::Constant(_v) => {},
Expression::UnaryOp(b) => {
let (_operator, _operator_pos, right) = &**b;
for_each_identifier_in_expression(&right, func);
pub trait IterIdentifiers {
fn for_each_value<F>(&self, func : &mut F) where F : FnMut(IdentifierIdx, usize) -> ();
}

impl IterIdentifiers for SpanExpression {
fn for_each_value<F>(&self, func : &mut F) where F : FnMut(IdentifierIdx, usize) -> () {
let (expr, span) = self;
match expr {
Expression::Named(id) => {
assert!(span.0 == span.1);
func(*id, span.0)
}
Expression::Constant(_v) => {}
Expression::UnaryOp(b) => {
let (_operator, _operator_pos, right) = &**b;
right.for_each_value(func);
}
Expression::BinOp(b) => {
let (left, _operator, _operator_pos, right) = &**b;
left.for_each_value(func);
right.for_each_value(func);
}
Expression::FuncCall(args) => {
for arg in args {
arg.for_each_value(func);
}
}
Expression::Array(b) => {
let (array, idx) = &**b;
array.for_each_value(func);
idx.for_each_value(func);
}
}
Expression::BinOp(b) => {
let (left, _operator, _operator_pos, right) = &**b;
for_each_identifier_in_expression(&left, func);
for_each_identifier_in_expression(&right, func);
},
Expression::Array(args) | Expression::FuncCall(args) => {
for arg in args {
for_each_identifier_in_expression(arg, func);
}
}

impl IterIdentifiers for SpanTypeExpression {
fn for_each_value<F>(&self, func : &mut F) where F : FnMut(IdentifierIdx, usize) -> () {
let (typ, _span) = self;
match typ {
TypeExpression::Named(_n) => {
// is type
}
TypeExpression::Array(b) => {
let (arr_typ, arr_size) = &**b;
arr_typ.for_each_value(func);
arr_size.for_each_value(func);
}
}
}
Expand All @@ -188,13 +234,12 @@ pub fn for_each_identifier_in_expression<F>((expr, span) : &SpanExpression, func
pub fn for_each_expression_in_block<F>(block : &Vec<SpanStatement>, func : &mut F) where F: FnMut(&SpanExpression) {
for (stmt, _span) in block {
match stmt {
Statement::Assign(to, v, _eq_sign_pos) => {
func(to);
Statement::Assign(to, v) => {
for t in to {
func(t);
}
func(v);
},
Statement::Mention(m) => {
func(m);
},
Statement::Block(b) => {
for_each_expression_in_block(b, func);
},
Expand All @@ -213,3 +258,22 @@ pub fn for_each_expression_in_module<F>(m : &Module, func : &mut F) where F : Fn
}
for_each_expression_in_block(&m.code, func);
}

pub struct GlobalContext {
real_types : HashMap<usize, TypeExpression>,
// aliases : todo!()
}

impl GlobalContext {
pub fn parse_to_type((expr, span) : &SpanExpression, errors : &mut Vec<ParsingError<Span>>) -> Option<TypeExpression> {
match expr {
Expression::Named(idx) => {todo!();},
Expression::Array(args) => {todo!();},
other => {
errors.push(error_basic_str(*span, "Unexpected part"));
return None
}
}
}
}

46 changes: 23 additions & 23 deletions src/code_generation/mod.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
use crate::{ast::*, errors::{ParsingError, error_basic_str}};


pub struct GlobalContext {

}

type ToAssignable = usize;

#[derive(Debug)]
Expand All @@ -20,7 +16,7 @@ pub enum Operation {
#[derive(Debug)]
pub struct LocalVar {
span : Span,
typ : Option<SpanExpression>,
typ : Option<SpanTypeExpression>,
identifier_type : IdentifierType
}

Expand Down Expand Up @@ -99,28 +95,32 @@ impl Flattened {
}
})
}
}

pub fn synthesize(module : &Module, errors : &mut Vec<ParsingError<Span>>) -> Flattened {
let mut result = Flattened{variables : Vec::new(), operations : Vec::new()};

for decl in &module.declarations {
result.variables.push(LocalVar{span : decl.span, typ : Some(decl.typ.clone()), identifier_type : decl.identifier_type})
}

for (stmt, stmt_span) in &module.code {
match stmt {
Statement::Assign(to, value_expr, eq_sign_pos) => {
if let Some(to_idx) = result.synthesize_assign_to_expr(to, errors) {
let value_idx = result.synthesize_expression(value_expr);
result.operations.push((Operation::Copy { out: to_idx, input: value_idx }, *eq_sign_pos))
pub fn synthesize(module : &Module, errors : &mut Vec<ParsingError<Span>>) -> Flattened {
let mut result = Flattened{variables : Vec::new(), operations : Vec::new()};

for decl in &module.declarations {
result.variables.push(LocalVar{span : decl.span, typ : Some(decl.typ.clone()), identifier_type : decl.identifier_type})
}

for (stmt, stmt_span) in &module.code {
match stmt {
Statement::Assign(to, value_expr) => {
/*if let Some(to_idx) = result.synthesize_assign_to_expr(to, errors) {
let value_idx = result.synthesize_expression(value_expr);
result.operations.push((Operation::Copy { out: to_idx, input: value_idx }, *eq_sign_pos))
}*/
},
other => {
todo!();
}
},
other => {
todo!();
}
}

result
}

result
pub fn typecheck(&mut self, errors : &mut Vec<ParsingError<Span>>) {

}
}
13 changes: 1 addition & 12 deletions src/dev_aid/lsp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ use crate::{parser::{perform_full_semantic_parse, FullParseResult}, dev_aid::syn

use super::syntax_highlighting::{IDETokenType, IDEIdentifierType, IDEToken};

use std::env;

static LSP_LOG_PATH : &str = if crate::tokenizer::const_eq_str(std::env::consts::OS, "windows") {
"C:\\Users\\lenna\\lsp_out.txt"
} else {
Expand All @@ -24,14 +22,6 @@ static LSP_LOG_PATH : &str = if crate::tokenizer::const_eq_str(std::env::consts:

thread_local!(static LSP_LOG: File = File::create(LSP_LOG_PATH).expect("Replacement terminal /home/lennart/lsp_out.txt could not be created"));

macro_rules! print {
($($arg:tt)*) => {{
use std::io::Write;
LSP_LOG.with(|mut file| {
write!(file, $($arg)*).unwrap();
})
}};
}
macro_rules! println {
($($arg:tt)*) => {{
use std::io::Write;
Expand Down Expand Up @@ -152,8 +142,7 @@ fn get_semantic_token_type_from_ide_token(tok : &IDEToken) -> u32 {
IDETokenType::Comment => 0,
IDETokenType::Keyword => 1,
IDETokenType::Operator => 2,
IDETokenType::PipelineStage => 7, // EVENT seems to get a good colour
IDETokenType::TimelineStage => 7,
IDETokenType::TimelineStage => 7,// EVENT seems to get a good colour
IDETokenType::Identifier(IDEIdentifierType::Value(IdentifierType::Input)) => 4,
IDETokenType::Identifier(IDEIdentifierType::Value(IdentifierType::Output)) => 4,
IDETokenType::Identifier(IDEIdentifierType::Value(IdentifierType::State)) => 3,
Expand Down
10 changes: 3 additions & 7 deletions src/dev_aid/syntax_highlighting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ pub enum IDETokenType {
Comment,
Keyword,
Operator,
PipelineStage,
TimelineStage,
Identifier(IDEIdentifierType),
Number,
Expand Down Expand Up @@ -60,7 +59,6 @@ fn pretty_print(file_text : &str, token_spans : &[CharSpan], ide_infos : &[IDETo
IDETokenType::Comment => Style::new().green().dim(),
IDETokenType::Keyword => Style::new().blue(),
IDETokenType::Operator => Style::new().white().bright(),
IDETokenType::PipelineStage => Style::new().red().bold(),
IDETokenType::TimelineStage => Style::new().red().bold(),
IDETokenType::Identifier(IDEIdentifierType::Unknown) => Style::new().red().underlined(),
IDETokenType::Identifier(IDEIdentifierType::Value(IdentifierType::Local)) => Style::new().blue().bright(),
Expand Down Expand Up @@ -97,14 +95,14 @@ fn add_ide_bracket_depths_recursive<'a>(result : &mut [IDEToken], current_depth
fn walk_name_color(ast : &ASTRoot, result : &mut [IDEToken]) {
for module in &ast.modules {
for decl in &module.declarations {
for_each_identifier_in_expression(&decl.typ, &mut |_name, position| {
decl.typ.for_each_value(&mut |_name, position| {
result[position].typ = IDETokenType::Identifier(IDEIdentifierType::Type);
});
//result[decl.name.position].typ = IDETokenType::Identifier(IDEIdentifierType::Value(decl.identifier_type));
}

for_each_expression_in_module(&module, &mut |expr| {
for_each_identifier_in_expression(expr, &mut |name, position| {
expr.for_each_value(&mut |name, position| {
result[position].typ = IDETokenType::Identifier(if let Some(l) = name.get_local() {
IDEIdentifierType::Value(module.declarations[l].identifier_type)
} else {
Expand All @@ -126,9 +124,7 @@ pub fn create_token_ide_info<'a>(parsed: &FullParseResult) -> Vec<IDEToken> {
} else if is_bracket(tok_typ) != IsBracket::NotABracket {
IDETokenType::InvalidBracket // Brackets are initially invalid. They should be overwritten by the token_hierarchy step. The ones that don't get overwritten are invalid
} else if is_symbol(tok_typ) {
if tok_typ == kw("@") {
IDETokenType::PipelineStage
} else if tok_typ == kw("#") {
if tok_typ == kw("#") {
IDETokenType::TimelineStage
} else {
IDETokenType::Operator
Expand Down
21 changes: 17 additions & 4 deletions src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,16 +111,29 @@ pub fn error_unopened_bracket(close_pos : usize, close_typ : TokenTypeIdx, open_
error_with_info(Span::from(close_pos), reason, vec![error_info_str(Span(open_after_pos, open_after_pos), "must be opened in scope after this")])
}

pub fn error_unexpected_token(expected : &[TokenTypeIdx], found : TokenTypeIdx, pos : usize, context : &str) -> ParsingError<Span> {
let expected_list_str = join_expected_list(expected);
error_unexpected_token_str(&expected_list_str, found, pos, context)
}

pub fn error_unexpected_token_str(expected_list_str : &str, found : TokenTypeIdx, pos : usize, context : &str) -> ParsingError<Span> {
let tok_typ_name = get_token_type_name(found);
error_basic(Span::from(pos), format!("Unexpected Token '{tok_typ_name}' while parsing {context}. Expected {expected_list_str}"))
}

pub fn error_unexpected_tree_node(expected : &[TokenTypeIdx], found : Option<&TokenTreeNode>, unexpected_eof_idx : usize, context : &str) -> ParsingError<Span> {
let expected_list_str = join_expected_list(expected);
error_unexpected_tree_node_str(&expected_list_str, found, unexpected_eof_idx, context)
}

pub fn error_unexpected_tree_node_str(expected_list_str : &str, found : Option<&TokenTreeNode>, unexpected_eof_idx : usize, context : &str) -> ParsingError<Span> {
match found {
None => {
error_basic(Span::from(unexpected_eof_idx), format!("Unexpected End of Scope while parsing {context}. Expected {expected_list_str}"))
},
}
Some(TokenTreeNode::PlainToken(tok, pos)) => {
let tok_typ_name = get_token_type_name(tok.get_type());
error_basic(Span::from(*pos), format!("Unexpected Token '{tok_typ_name}' while parsing {context}. Expected {expected_list_str}"))
},
error_unexpected_token_str(expected_list_str, tok.get_type(), *pos, context)
}
Some(TokenTreeNode::Block(typ, _, span)) => {
let tok_typ_name = get_token_type_name(*typ);
error_basic(*span, format!("Unexpected Block '{tok_typ_name}' while parsing {context}. Expected {expected_list_str}"))
Expand Down
Loading

0 comments on commit d18d935

Please sign in to comment.