Skip to content

Commit

Permalink
parse floats, unescape strings and chars
Browse files Browse the repository at this point in the history
  • Loading branch information
edg-l committed Jan 19, 2024
1 parent 68423e9 commit 3916339
Show file tree
Hide file tree
Showing 10 changed files with 130 additions and 13 deletions.
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions crates/concrete_ast/src/expressions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ pub enum Expression {
pub enum SimpleExpr {
ConstBool(bool),
ConstChar(char),
ConstInt(u64),
ConstFloat(()),
ConstInt(u128),
ConstFloat(String),
ConstStr(String),
Path(PathOp),
}
Expand Down
28 changes: 25 additions & 3 deletions crates/concrete_codegen_mlir/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ use melior::{
cf, func, memref,
},
ir::{
attribute::{FlatSymbolRefAttribute, IntegerAttribute, StringAttribute, TypeAttribute},
attribute::{
FlatSymbolRefAttribute, FloatAttribute, IntegerAttribute, StringAttribute,
TypeAttribute,
},
r#type::{FunctionType, IntegerType, MemRefType},
Block, BlockRef, Location, Module as MeliorModule, Operation, Region, Type, Value,
ValueLike,
Expand Down Expand Up @@ -133,6 +136,7 @@ impl<'ctx, 'parent> ScopeContext<'ctx, 'parent> {
"u32" | "i32" => IntegerType::new(context, 32).into(),
"u16" | "i16" => IntegerType::new(context, 16).into(),
"u8" | "i8" => IntegerType::new(context, 8).into(),
"char" => IntegerType::new(context, 32).into(),
"f32" => Type::float32(context),
"f64" => Type::float64(context),
"bool" => IntegerType::new(context, 1).into(),
Expand Down Expand Up @@ -658,13 +662,31 @@ fn compile_expression<'ctx, 'parent: 'ctx>(
} else {
IntegerType::new(context, 64).into()
};
let value = IntegerAttribute::new((*value) as i64, int_type);
let value = IntegerAttribute::new(
(*value).try_into().expect("integer is too big"),
int_type,
);
Ok(block
.append_operation(arith::constant(context, value.into(), location))
.result(0)?
.into())
}
SimpleExpr::ConstFloat(value) => {
let float_type = if let Some(type_info) = type_info {
scope_ctx.resolve_type_spec(context, type_info)?
} else {
Type::float64(context)
};
let value = FloatAttribute::new(
context,
value.parse().expect("failed to parse float"),
float_type,
);
Ok(block
.append_operation(arith::constant(context, value.into(), location))
.result(0)?
.into())
}
SimpleExpr::ConstFloat(_) => todo!(),
SimpleExpr::ConstStr(_) => todo!(),
SimpleExpr::Path(value) => compile_path_op(session, context, scope_ctx, block, value),
},
Expand Down
33 changes: 33 additions & 0 deletions crates/concrete_driver/tests/programs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,3 +130,36 @@ fn test_import() {
let code = output.status.code().unwrap();
assert_eq!(code, 8);
}

#[test]
fn test_floats() {
let source = r#"
mod Simple {
fn main() -> i64 {
let a: f32 = my_f32(2.0, 4.0);
let b: f64 = my_f64(2.0, 4.0);
return 1;
}
fn my_f32(x: f32, y: f32) -> f32 {
let literal: f32 = 2.0;
let literal2: f32 = 2.;
let literal3: f32 = .1;
return x + y + literal2 + literal3;
}
fn my_f64(x: f64, y: f64) -> f64 {
let literal: f64 = 2.0;
let literal2: f64 = 2.;
let literal3: f64 = .1;
return x + y + literal2 + literal3;
}
}
"#;

let result = compile_program(source, "floats", false).expect("failed to compile");

let output = run_program(&result.binary_file).expect("failed to run");
let code = output.status.code().unwrap();
assert_eq!(code, 1);
}
1 change: 1 addition & 0 deletions crates/concrete_parser/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ concrete_ast = { path = "../concrete_ast"}
salsa = { git = "https://github.com/salsa-rs/salsa.git", package = "salsa-2022" }
ariadne = { version = "0.4.0", features = ["auto-color"] }
itertools = "0.12.0"
unescaper = "0.1.3"

[build-dependencies]
lalrpop = "0.20.0"
6 changes: 5 additions & 1 deletion crates/concrete_parser/src/grammar.lalrpop
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@ extern {

// literals
"identifier" => Token::Identifier(<String>),
"integer" => Token::Integer(<u64>),
"integer" => Token::Integer(<u128>),
"float" => Token::Float(<String>),
"string" => Token::String(<String>),
"char" => Token::Char(<char>),
"boolean" => Token::Boolean(<bool>),

// Other
Expand Down Expand Up @@ -341,8 +343,10 @@ pub UnaryOp: ast::expressions::UnaryOp = {

pub(crate) SimpleExpr: ast::expressions::SimpleExpr = {
<"integer"> => ast::expressions::SimpleExpr::ConstInt(<>),
<"float"> => ast::expressions::SimpleExpr::ConstFloat(<>),
<"boolean"> => ast::expressions::SimpleExpr::ConstBool(<>),
<"string"> => ast::expressions::SimpleExpr::ConstStr(<>),
<"char"> => ast::expressions::SimpleExpr::ConstChar(<>),
<PathOp> => ast::expressions::SimpleExpr::Path(<>),
}

Expand Down
8 changes: 4 additions & 4 deletions crates/concrete_parser/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ mod ModuleName {
"##;
let lexer = Lexer::new(source);
let parser = grammar::ProgramParser::new();
dbg!(parser.parse(lexer).unwrap());
parser.parse(lexer).unwrap();
}

#[test]
Expand All @@ -104,7 +104,7 @@ mod ModuleName {
}"##;
let lexer = Lexer::new(source);
let parser = grammar::ProgramParser::new();
dbg!(parser.parse(lexer).unwrap());
parser.parse(lexer).unwrap();
}

#[test]
Expand All @@ -116,7 +116,7 @@ mod ModuleName {
}"##;
let lexer = Lexer::new(source);
let parser = grammar::ProgramParser::new();
dbg!(parser.parse(lexer).unwrap());
parser.parse(lexer).unwrap();
}

#[test]
Expand All @@ -128,6 +128,6 @@ mod ModuleName {
}"##;
let lexer = Lexer::new(source);
let parser = grammar::ProgramParser::new();
dbg!(parser.parse(lexer).unwrap());
parser.parse(lexer).unwrap();
}
}
19 changes: 16 additions & 3 deletions crates/concrete_parser/src/tokens.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,25 @@ pub enum Token {
Identifier(String),

// Literals
#[regex(r"\d+", |lex| lex.slice().parse::<u64>().unwrap())]
Integer(u64),
#[regex(r#""(?:[^"]|\\")*""#, |lex| lex.slice().to_string())]
#[regex(r"\d+", |lex| lex.slice().parse::<u128>().unwrap(), priority = 2)]
Integer(u128),
#[regex(r"([0-9]+([.][0-9]*)?|[.][0-9]+)", |lex| lex.slice().to_string(), priority = 1)]
Float(String),
#[regex(r#""(?:[^"]|\\")*""#, |lex| {
let slice = lex.slice();
let len = slice.len();
unescaper::unescape(&slice[1..(len-1)]).expect("failed to unescape string")
})]
String(String),
#[regex(r"(true|false)", |lex| lex.slice().parse::<bool>().unwrap())]
Boolean(bool),
#[regex(r#"'(?:[^']|\\')*'"#, |lex| {
let slice = lex.slice();
let len = slice.len();
let real_char = unescaper::unescape(&slice[1..(len-1)]).expect("failed to unescape char").to_string();
real_char.chars().next().unwrap()
})]
Char(char),

#[token("(")]
LeftParen,
Expand Down
13 changes: 13 additions & 0 deletions examples/chars.con
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
mod Simple {
fn main() -> i64 {
let a: char = hello_chars('\t');
return 1;
}

fn hello_chars(a: char) -> char {
let x: char = 'b';
let newline: char = '\n';

return x + newline + a;
}
}
21 changes: 21 additions & 0 deletions examples/floats.con
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
mod Simple {
fn main() -> i64 {
let a: f32 = my_f32(2.0, 4.0);
let b: f64 = my_f64(2.0, 4.0);
return 1;
}

fn my_f32(x: f32, y: f32) -> f32 {
let literal: f32 = 2.0;
let literal2: f32 = 2.;
let literal3: f32 = .1;
return x + y + literal2 + literal3;
}

fn my_f64(x: f64, y: f64) -> f64 {
let literal: f64 = 2.0;
let literal2: f64 = 2.;
let literal3: f64 = .1;
return x + y + literal2 + literal3;
}
}

0 comments on commit 3916339

Please sign in to comment.