Compare commits
5 Commits
a3d923da12
...
be3c415a57
Author | SHA1 | Date | |
---|---|---|---|
be3c415a57 | |||
5b59d0689b | |||
22160b0802 | |||
25fb6bf0fd | |||
a09bccb255 |
@ -58,7 +58,7 @@ Big features that I want later but are not necessary:
|
||||
- LSP implementation
|
||||
|
||||
Smaller features:
|
||||
- Hex-numbers
|
||||
- ~~Hex-numbers~~
|
||||
- Bitwise operations
|
||||
- Easier way to initialize arrays with a single value
|
||||
- Void-returns (`return;` for void-returning functions)
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
|
||||
fn main() -> u32 {
|
||||
let value = 6;
|
||||
let other = 15;
|
||||
let value = 0b110;
|
||||
let other = 0o17;
|
||||
|
||||
return value * other + 7 * -value;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Main
|
||||
fn main() -> bool {
|
||||
return 5 == fibonacci(5);
|
||||
return 144 == fibonacci(0xc);
|
||||
}
|
||||
|
||||
// Fibonacci
|
||||
|
@ -7,7 +7,7 @@ import std::new_string;
|
||||
import std::add_num_to_str;
|
||||
import std::concat_strings;
|
||||
|
||||
fn main() -> u8 {
|
||||
fn main() {
|
||||
let mut test = from_str("hello");
|
||||
|
||||
concat_strings(&mut test, from_str(" world"));
|
||||
@ -21,5 +21,5 @@ fn main() -> u8 {
|
||||
|
||||
free_string(&test);
|
||||
|
||||
return 8;
|
||||
return;
|
||||
}
|
||||
|
@ -89,7 +89,9 @@ impl mir::Block {
|
||||
}
|
||||
|
||||
if let Some((_, ret_expr)) = &self.return_expression {
|
||||
allocated.extend(ret_expr.allocate(scope));
|
||||
if let Some(ret_expr) = ret_expr {
|
||||
allocated.extend(ret_expr.allocate(scope));
|
||||
}
|
||||
}
|
||||
|
||||
allocated
|
||||
|
@ -164,7 +164,7 @@ pub struct StructExpression {
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Block(
|
||||
pub Vec<BlockLevelStatement>,
|
||||
pub Option<(ReturnType, Expression)>,
|
||||
pub Option<(ReturnType, Option<Expression>)>,
|
||||
pub TokenRange,
|
||||
);
|
||||
|
||||
@ -177,7 +177,7 @@ pub enum BlockLevelStatement {
|
||||
_i: ImportStatement,
|
||||
},
|
||||
Expression(Expression),
|
||||
Return(ReturnType, Expression),
|
||||
Return(ReturnType, Option<Expression>),
|
||||
ForLoop(String, TokenRange, Expression, Expression, Block),
|
||||
WhileLoop(Expression, Block),
|
||||
}
|
||||
|
@ -153,6 +153,34 @@ impl Parse for PrimaryExpression {
|
||||
Expression(Kind::VariableName(v.clone()), stream.get_range().unwrap())
|
||||
}
|
||||
}
|
||||
Token::BinaryValue(v) => {
|
||||
stream.next(); // Consume octal
|
||||
Expression(
|
||||
Kind::Literal(Literal::Integer(
|
||||
u128::from_str_radix(&v, 2).expect("Binary is not parseable as u128!"),
|
||||
)),
|
||||
stream.get_range().unwrap(),
|
||||
)
|
||||
}
|
||||
Token::OctalValue(v) => {
|
||||
stream.next(); // Consume octal
|
||||
Expression(
|
||||
Kind::Literal(Literal::Integer(
|
||||
u128::from_str_radix(&v, 8).expect("Octal is not parseable as u128!"),
|
||||
)),
|
||||
stream.get_range().unwrap(),
|
||||
)
|
||||
}
|
||||
Token::HexadecimalValue(v) => {
|
||||
stream.next(); // Consume hexadecimal
|
||||
Expression(
|
||||
Kind::Literal(Literal::Integer(
|
||||
u128::from_str_radix(&v, 16)
|
||||
.expect("Hexadecimal is not parseable as u128!"),
|
||||
)),
|
||||
stream.get_range().unwrap(),
|
||||
)
|
||||
}
|
||||
Token::DecimalValue(v) => {
|
||||
stream.next(); // Consume decimal
|
||||
if let (Some(Token::Dot), Some(Token::DecimalValue(fractional))) =
|
||||
@ -172,7 +200,8 @@ impl Parse for PrimaryExpression {
|
||||
} else {
|
||||
Expression(
|
||||
Kind::Literal(Literal::Integer(
|
||||
v.parse().expect("Integer is not parseable as u128!"),
|
||||
u128::from_str_radix(&v, 10)
|
||||
.expect("Integer is not parseable as u128!"),
|
||||
)),
|
||||
stream.get_range().unwrap(),
|
||||
)
|
||||
@ -527,7 +556,7 @@ impl Parse for Block {
|
||||
stream.expect(Token::BraceOpen)?;
|
||||
|
||||
while !matches!(stream.peek(), Some(Token::BraceClose)) {
|
||||
if let Some((_, e)) = return_stmt.take() {
|
||||
if let Some((_, Some(e))) = return_stmt.take() {
|
||||
// Special list of expressions that are simply not warned about,
|
||||
// if semicolon is missing.
|
||||
if !matches!(e, Expression(ExpressionKind::IfExpr(_), _)) {
|
||||
@ -668,7 +697,7 @@ impl Parse for BlockLevelStatement {
|
||||
},
|
||||
Some(Token::ReturnKeyword) => {
|
||||
stream.next();
|
||||
let exp = stream.parse()?;
|
||||
let exp = stream.parse().ok();
|
||||
stream.expect(Token::Semi)?;
|
||||
Stmt::Return(ReturnType::Hard, exp)
|
||||
}
|
||||
@ -688,7 +717,7 @@ impl Parse for BlockLevelStatement {
|
||||
if stream.expect(Token::Semi).is_ok() {
|
||||
Stmt::Expression(e)
|
||||
} else {
|
||||
Stmt::Return(ReturnType::Soft, e)
|
||||
Stmt::Return(ReturnType::Soft, Some(e))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,8 +3,8 @@ use std::path::PathBuf;
|
||||
use crate::{
|
||||
ast::{self},
|
||||
mir::{
|
||||
self, CustomTypeKey, ModuleMap, NamedVariableRef, SourceModuleId, StmtKind, StructField,
|
||||
StructType, WhileStatement,
|
||||
self, CustomTypeKey, ModuleMap, NamedVariableRef, ReturnKind, SourceModuleId, StmtKind,
|
||||
StructField, StructType, WhileStatement,
|
||||
},
|
||||
};
|
||||
|
||||
@ -166,7 +166,11 @@ impl ast::Block {
|
||||
(StmtKind::Expression(e.process(module_id)), e.1)
|
||||
}
|
||||
ast::BlockLevelStatement::Return(_, e) => {
|
||||
(StmtKind::Expression(e.process(module_id)), e.1)
|
||||
if let Some(e) = e {
|
||||
(StmtKind::Expression(e.process(module_id)), e.1)
|
||||
} else {
|
||||
panic!(); // Should never happen?
|
||||
}
|
||||
}
|
||||
ast::BlockLevelStatement::ForLoop(counter, counter_range, start, end, block) => {
|
||||
let counter_var = NamedVariableRef(
|
||||
@ -249,7 +253,11 @@ impl ast::Block {
|
||||
}
|
||||
|
||||
let return_expression = if let Some(r) = &self.1 {
|
||||
Some((r.0.into(), Box::new(r.1.process(module_id))))
|
||||
if let Some(expr) = &r.1 {
|
||||
Some((r.0.into(), Some(Box::new(expr.process(module_id)))))
|
||||
} else {
|
||||
Some((ReturnKind::Hard, None))
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
@ -632,12 +632,12 @@ impl FunctionDefinitionKind {
|
||||
}
|
||||
|
||||
if let Some(debug) = &scope.debug {
|
||||
let location = &block
|
||||
.return_meta()
|
||||
.into_debug(scope.tokens, debug.scope)
|
||||
.unwrap();
|
||||
let location = debug.info.location(&debug.scope, *location);
|
||||
scope.block.set_terminator_location(location).unwrap();
|
||||
if let Some(location) =
|
||||
&block.return_meta().into_debug(scope.tokens, debug.scope)
|
||||
{
|
||||
let location = debug.info.location(&debug.scope, *location);
|
||||
scope.block.set_terminator_location(location).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
mir::FunctionDefinitionKind::Extern(_) => {}
|
||||
@ -664,17 +664,25 @@ impl mir::Block {
|
||||
}
|
||||
|
||||
if let Some((kind, expr)) = &self.return_expression {
|
||||
let ret = expr.codegen(&mut scope, &mut state.load(true))?;
|
||||
match kind {
|
||||
mir::ReturnKind::Hard => {
|
||||
if let Some(ret) = ret {
|
||||
scope.block.terminate(Term::Ret(ret.instr())).unwrap();
|
||||
} else {
|
||||
scope.block.terminate(Term::RetVoid).unwrap();
|
||||
if let Some(expr) = expr {
|
||||
let ret = expr.codegen(&mut scope, &mut state.load(true))?;
|
||||
match kind {
|
||||
mir::ReturnKind::Hard => {
|
||||
if let Some(ret) = ret {
|
||||
scope.block.terminate(Term::Ret(ret.instr())).unwrap();
|
||||
} else {
|
||||
scope.block.terminate(Term::RetVoid).unwrap();
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
Ok(None)
|
||||
mir::ReturnKind::Soft => Ok(ret),
|
||||
}
|
||||
mir::ReturnKind::Soft => Ok(ret),
|
||||
} else {
|
||||
match kind {
|
||||
mir::ReturnKind::Hard => scope.block.terminate(Term::RetVoid).unwrap(),
|
||||
mir::ReturnKind::Soft => {}
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
} else {
|
||||
Ok(None)
|
||||
|
@ -1,13 +1,28 @@
|
||||
use std::{fmt::Debug, str::Chars};
|
||||
use std::{
|
||||
fmt::Debug,
|
||||
ops::{Add, AddAssign},
|
||||
str::Chars,
|
||||
};
|
||||
|
||||
static BINARY_NUMERICS: &[char] = &['0', '1'];
|
||||
static OCTAL_NUMERICS: &[char] = &['0', '1', '2', '3', '4', '5', '6', '7'];
|
||||
static DECIMAL_NUMERICS: &[char] = &['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
|
||||
static HEXADECIMAL_NUMERICS: &[char] = &[
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
|
||||
];
|
||||
|
||||
#[derive(Eq, PartialEq, Clone, PartialOrd, Ord)]
|
||||
pub enum Token {
|
||||
/// Values
|
||||
Identifier(String),
|
||||
/// Number with at most one decimal point
|
||||
/// Number in the decimal base
|
||||
DecimalValue(String),
|
||||
/// Integer number in the hexadecimal base
|
||||
HexadecimalValue(String),
|
||||
/// Integer number in the octal base
|
||||
OctalValue(String),
|
||||
/// Integer number in the binary base
|
||||
BinaryValue(String),
|
||||
/// Some character literal that was surrounded by 'single-quotes'.
|
||||
CharLit(String),
|
||||
/// Some string literal that was surrounded by "double-quotes".
|
||||
@ -130,6 +145,9 @@ impl ToString for Token {
|
||||
match &self {
|
||||
Token::Identifier(ident) => ident.clone(),
|
||||
Token::DecimalValue(val) => val.to_string(),
|
||||
Token::HexadecimalValue(val) => format!("0x{}", val),
|
||||
Token::OctalValue(val) => format!("0o{}", val),
|
||||
Token::BinaryValue(val) => format!("0b{}", val),
|
||||
Token::CharLit(lit) => format!("\'{}\'", lit),
|
||||
Token::StringLit(lit) => format!("\"{}\"", lit),
|
||||
Token::LetKeyword => String::from("let"),
|
||||
@ -348,15 +366,43 @@ pub fn tokenize<T: Into<String>>(to_tokenize: T) -> Result<Vec<FullToken>, Error
|
||||
}
|
||||
// Decimals
|
||||
c if DECIMAL_NUMERICS.contains(c) => {
|
||||
let mut value = character.to_string();
|
||||
let mut value = NumberType::Decimal(character.to_string());
|
||||
let mut numerics = DECIMAL_NUMERICS;
|
||||
if let Some(second) = cursor.second() {
|
||||
if cursor.first() == Some('x')
|
||||
&& HEXADECIMAL_NUMERICS
|
||||
.contains(&second.to_lowercase().next().unwrap_or('.'))
|
||||
{
|
||||
cursor.next();
|
||||
value = NumberType::Hexadecimal(String::new());
|
||||
numerics = HEXADECIMAL_NUMERICS;
|
||||
} else if cursor.first() == Some('o')
|
||||
&& OCTAL_NUMERICS.contains(&second.to_lowercase().next().unwrap_or('.'))
|
||||
{
|
||||
cursor.next();
|
||||
value = NumberType::Octal(String::new());
|
||||
numerics = OCTAL_NUMERICS;
|
||||
} else if cursor.first() == Some('b')
|
||||
&& BINARY_NUMERICS.contains(&second.to_lowercase().next().unwrap_or('.'))
|
||||
{
|
||||
cursor.next();
|
||||
value = NumberType::Binary(String::new());
|
||||
numerics = BINARY_NUMERICS;
|
||||
}
|
||||
}
|
||||
while let Some(c) = cursor.first() {
|
||||
if !DECIMAL_NUMERICS.contains(&c) {
|
||||
if !numerics.contains(&c.to_lowercase().next().unwrap_or('.')) {
|
||||
break;
|
||||
}
|
||||
value += &c.to_string();
|
||||
value += c;
|
||||
cursor.next();
|
||||
}
|
||||
Token::DecimalValue(value)
|
||||
match value {
|
||||
NumberType::Decimal(dec) => Token::DecimalValue(dec),
|
||||
NumberType::Hexadecimal(hex) => Token::HexadecimalValue(hex),
|
||||
NumberType::Octal(oct) => Token::OctalValue(oct),
|
||||
NumberType::Binary(bin) => Token::BinaryValue(bin),
|
||||
}
|
||||
}
|
||||
'-' if cursor.first() == Some('>') => {
|
||||
cursor.next(); // Eat `>`
|
||||
@ -411,6 +457,26 @@ fn escape_char(c: &char) -> char {
|
||||
}
|
||||
}
|
||||
|
||||
enum NumberType {
|
||||
Decimal(String),
|
||||
Hexadecimal(String),
|
||||
Octal(String),
|
||||
Binary(String),
|
||||
}
|
||||
|
||||
impl AddAssign<char> for NumberType {
|
||||
fn add_assign(&mut self, rhs: char) {
|
||||
*self = match self {
|
||||
NumberType::Decimal(val) => NumberType::Decimal(val.to_owned() + &rhs.to_string()),
|
||||
NumberType::Hexadecimal(val) => {
|
||||
NumberType::Hexadecimal(val.to_owned() + &rhs.to_string())
|
||||
}
|
||||
NumberType::Octal(val) => NumberType::Octal(val.to_owned() + &rhs.to_string()),
|
||||
NumberType::Binary(val) => NumberType::Binary(val.to_owned() + &rhs.to_string()),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(thiserror::Error, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub enum Error {
|
||||
#[error("Invalid token '{}' ", .0)]
|
||||
|
@ -78,7 +78,7 @@ pub fn parse_module<'map, T: Into<String>>(
|
||||
map.set_tokens(id, tokens.clone());
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
dbg!(&tokens);
|
||||
println!("{:#?}", &tokens);
|
||||
|
||||
Ok((id, tokens))
|
||||
}
|
||||
|
@ -142,9 +142,15 @@ impl Display for Block {
|
||||
write!(inner_f, "{}", statement)?;
|
||||
}
|
||||
if let Some(ret) = &self.return_expression {
|
||||
let ret_fmt = if let Some(ret) = &ret.1 {
|
||||
format!("{}", ret)
|
||||
} else {
|
||||
String::from("void")
|
||||
};
|
||||
|
||||
match ret.0 {
|
||||
ReturnKind::Hard => writeln!(inner_f, "Return(Hard): {}", ret.1),
|
||||
ReturnKind::Soft => writeln!(inner_f, "Return(Soft): {}", ret.1),
|
||||
ReturnKind::Hard => writeln!(inner_f, "Return(Hard): {}", ret_fmt),
|
||||
ReturnKind::Soft => writeln!(inner_f, "Return(Soft): {}", ret_fmt),
|
||||
}?;
|
||||
} else {
|
||||
writeln!(inner_f, "No Return")?;
|
||||
|
@ -367,7 +367,7 @@ impl StructType {
|
||||
|
||||
enum BlockReturn<'b> {
|
||||
Early(&'b Statement),
|
||||
Normal(ReturnKind, &'b Expression),
|
||||
Normal(ReturnKind, &'b Option<Box<Expression>>),
|
||||
}
|
||||
|
||||
impl Block {
|
||||
@ -394,7 +394,7 @@ impl Block {
|
||||
pub fn return_meta(&self) -> Metadata {
|
||||
self.return_expression
|
||||
.as_ref()
|
||||
.map(|e| e.1 .1)
|
||||
.map(|e| e.1.as_ref().map(|e| e.1).unwrap_or(Metadata::default()))
|
||||
.or(self.statements.last().map(|s| s.1))
|
||||
.unwrap_or(self.meta)
|
||||
}
|
||||
@ -420,15 +420,27 @@ impl Block {
|
||||
self.return_expression
|
||||
.as_ref()
|
||||
.ok_or(ReturnTypeOther::NoBlockReturn(self.meta))
|
||||
.and_then(|(kind, stmt)| Ok((*kind, stmt.return_type(refs, mod_id)?.1)))
|
||||
.and_then(|(kind, stmt)| {
|
||||
Ok((
|
||||
*kind,
|
||||
stmt.as_ref()
|
||||
.and_then(|s| s.return_type(refs, mod_id).ok())
|
||||
.map(|s| s.1)
|
||||
.unwrap_or(TypeKind::Void),
|
||||
))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn backing_var(&self) -> Option<&NamedVariableRef> {
|
||||
match self.return_expr().ok()? {
|
||||
BlockReturn::Early(statement) => statement.backing_var(),
|
||||
BlockReturn::Normal(kind, expr) => {
|
||||
if kind == ReturnKind::Soft {
|
||||
expr.backing_var()
|
||||
if let Some(expr) = expr {
|
||||
if kind == ReturnKind::Soft {
|
||||
expr.backing_var()
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
@ -328,7 +328,7 @@ impl FunctionDefinition {
|
||||
pub struct Block {
|
||||
/// List of non-returning statements
|
||||
pub statements: Vec<Statement>,
|
||||
pub return_expression: Option<(ReturnKind, Box<Expression>)>,
|
||||
pub return_expression: Option<(ReturnKind, Option<Box<Expression>>)>,
|
||||
pub meta: Metadata,
|
||||
}
|
||||
|
||||
|
@ -462,11 +462,15 @@ impl Block {
|
||||
ReturnKind::Hard => state.scope.return_type_hint.clone(),
|
||||
ReturnKind::Soft => hint_t.cloned(),
|
||||
};
|
||||
let res = expr.typecheck(&mut state, &typerefs, ret_hint_t.as_ref());
|
||||
Ok((
|
||||
*return_kind,
|
||||
state.or_else(res, TypeKind::Vague(Vague::Unknown), expr.1),
|
||||
))
|
||||
if let Some(expr) = expr {
|
||||
let res = expr.typecheck(&mut state, &typerefs, ret_hint_t.as_ref());
|
||||
Ok((
|
||||
*return_kind,
|
||||
state.or_else(res, TypeKind::Vague(Vague::Unknown), expr.1),
|
||||
))
|
||||
} else {
|
||||
Ok((*return_kind, TypeKind::Void))
|
||||
}
|
||||
} else {
|
||||
Ok((ReturnKind::Soft, TypeKind::Void))
|
||||
}
|
||||
|
@ -266,8 +266,10 @@ impl Block {
|
||||
|
||||
// If there is a return expression, infer it's type
|
||||
if let Some(ret_expr) = &mut self.return_expression {
|
||||
let ret_res = ret_expr.1.infer_types(&mut state, &inner_refs);
|
||||
state.ok(ret_res, ret_expr.1 .1);
|
||||
if let Some(expr) = &mut ret_expr.1 {
|
||||
let ret_res = expr.infer_types(&mut state, &inner_refs);
|
||||
state.ok(ret_res, expr.1);
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch the declared return type
|
||||
|
@ -17,7 +17,7 @@ use util::assert_err;
|
||||
|
||||
mod util;
|
||||
|
||||
fn test(source: &str, name: &str, expected_exit_code: i32) {
|
||||
fn test(source: &str, name: &str, expected_exit_code: Option<i32>) {
|
||||
assert_err(assert_err(std::panic::catch_unwind(|| {
|
||||
let mut map = Default::default();
|
||||
let (id, tokens) = assert_err(parse_module(source, name, &mut map));
|
||||
@ -50,7 +50,9 @@ fn test(source: &str, name: &str, expected_exit_code: i32) {
|
||||
let executed = Command::new(&out_path).output();
|
||||
std::fs::remove_file(out_path).unwrap();
|
||||
|
||||
assert_eq!(expected_exit_code, executed.unwrap().status.code().unwrap());
|
||||
if let Some(expected_exit_code) = expected_exit_code {
|
||||
assert_eq!(expected_exit_code, executed.unwrap().status.code().unwrap());
|
||||
}
|
||||
|
||||
Ok::<(), ()>(())
|
||||
})))
|
||||
@ -58,77 +60,125 @@ fn test(source: &str, name: &str, expected_exit_code: i32) {
|
||||
|
||||
#[test]
|
||||
fn arithmetic_compiles_well() {
|
||||
test(include_str!("../../examples/arithmetic.reid"), "test", 48);
|
||||
test(
|
||||
include_str!("../../examples/arithmetic.reid"),
|
||||
"test",
|
||||
Some(48),
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn array_structs_compiles_well() {
|
||||
test(include_str!("../../examples/array_structs.reid"), "test", 5);
|
||||
test(
|
||||
include_str!("../../examples/array_structs.reid"),
|
||||
"test",
|
||||
Some(5),
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn array_compiles_well() {
|
||||
test(include_str!("../../examples/array.reid"), "test", 3);
|
||||
test(include_str!("../../examples/array.reid"), "test", Some(3));
|
||||
}
|
||||
#[test]
|
||||
fn borrow_compiles_well() {
|
||||
test(include_str!("../../examples/borrow.reid"), "test", 17);
|
||||
test(include_str!("../../examples/borrow.reid"), "test", Some(17));
|
||||
}
|
||||
#[test]
|
||||
fn borrow_hard_compiles_well() {
|
||||
test(include_str!("../../examples/borrow_hard.reid"), "test", 17);
|
||||
test(
|
||||
include_str!("../../examples/borrow_hard.reid"),
|
||||
"test",
|
||||
Some(17),
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn cast_compiles_well() {
|
||||
test(include_str!("../../examples/cast.reid"), "test", 6);
|
||||
test(include_str!("../../examples/cast.reid"), "test", Some(6));
|
||||
}
|
||||
#[test]
|
||||
fn char_compiles_well() {
|
||||
test(include_str!("../../examples/char.reid"), "test", 98);
|
||||
test(include_str!("../../examples/char.reid"), "test", Some(98));
|
||||
}
|
||||
#[test]
|
||||
fn div_mod_compiles_well() {
|
||||
test(include_str!("../../examples/div_mod.reid"), "test", 12);
|
||||
test(
|
||||
include_str!("../../examples/div_mod.reid"),
|
||||
"test",
|
||||
Some(12),
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn fibonacci_compiles_well() {
|
||||
test(include_str!("../../examples/fibonacci.reid"), "test", 1);
|
||||
test(
|
||||
include_str!("../../examples/fibonacci.reid"),
|
||||
"test",
|
||||
Some(1),
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn float_compiles_well() {
|
||||
test(include_str!("../../examples/float.reid"), "test", 1);
|
||||
test(include_str!("../../examples/float.reid"), "test", Some(1));
|
||||
}
|
||||
#[test]
|
||||
fn hello_world_compiles_well() {
|
||||
test(include_str!("../../examples/hello_world.reid"), "test", 8);
|
||||
test(
|
||||
include_str!("../../examples/hello_world.reid"),
|
||||
"test",
|
||||
None,
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn mutable_compiles_well() {
|
||||
test(include_str!("../../examples/mutable.reid"), "test", 21);
|
||||
test(
|
||||
include_str!("../../examples/mutable.reid"),
|
||||
"test",
|
||||
Some(21),
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn ptr_compiles_well() {
|
||||
test(include_str!("../../examples/ptr.reid"), "test", 5);
|
||||
test(include_str!("../../examples/ptr.reid"), "test", Some(5));
|
||||
}
|
||||
#[test]
|
||||
fn std_test_compiles_well() {
|
||||
test(include_str!("../../examples/std_test.reid"), "test", 3);
|
||||
test(
|
||||
include_str!("../../examples/std_test.reid"),
|
||||
"test",
|
||||
Some(3),
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn strings_compiles_well() {
|
||||
test(include_str!("../../examples/strings.reid"), "test", 5);
|
||||
test(include_str!("../../examples/strings.reid"), "test", Some(5));
|
||||
}
|
||||
#[test]
|
||||
fn struct_compiles_well() {
|
||||
test(include_str!("../../examples/struct.reid"), "test", 17);
|
||||
test(include_str!("../../examples/struct.reid"), "test", Some(17));
|
||||
}
|
||||
#[test]
|
||||
fn loops_compiles_well() {
|
||||
test(include_str!("../../examples/loops.reid"), "test", 10);
|
||||
test(include_str!("../../examples/loops.reid"), "test", Some(10));
|
||||
}
|
||||
#[test]
|
||||
fn ptr_hard_compiles_well() {
|
||||
test(include_str!("../../examples/ptr_hard.reid"), "test", 0);
|
||||
test(
|
||||
include_str!("../../examples/ptr_hard.reid"),
|
||||
"test",
|
||||
Some(0),
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn loop_hard_compiles_well() {
|
||||
test(include_str!("../../examples/loop_hard.reid"), "test", 0);
|
||||
test(
|
||||
include_str!("../../examples/loop_hard.reid"),
|
||||
"test",
|
||||
Some(0),
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn custom_binop_compiles_well() {
|
||||
test(
|
||||
include_str!("../../examples/custom_binop.reid"),
|
||||
"test",
|
||||
Some(21),
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user