ran rust format
This commit is contained in:
54
src/ast.rs
54
src/ast.rs
@@ -6,7 +6,9 @@ pub struct IdGenerator {
|
|||||||
|
|
||||||
impl IdGenerator {
|
impl IdGenerator {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
IdGenerator{counter: RefCell::new(0)}
|
IdGenerator {
|
||||||
|
counter: RefCell::new(0),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn next(&self) -> String {
|
pub fn next(&self) -> String {
|
||||||
@@ -16,32 +18,31 @@ impl IdGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_unit() -> TypeUsage {
|
pub fn new_unit() -> TypeUsage {
|
||||||
TypeUsage::Named(NamedTypeUsage{
|
TypeUsage::Named(NamedTypeUsage {
|
||||||
name: Identifier{
|
name: Identifier {
|
||||||
name: Spanned{
|
name: Spanned {
|
||||||
span: Span{left: 0, right: 0}, //todo: figure out a sane value for these
|
span: Span { left: 0, right: 0 }, //todo: figure out a sane value for these
|
||||||
value: "unit".to_string(),
|
value: "unit".to_string(),
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_never() -> TypeUsage {
|
pub fn new_never() -> TypeUsage {
|
||||||
TypeUsage::Named(NamedTypeUsage{
|
TypeUsage::Named(NamedTypeUsage {
|
||||||
name: Identifier{
|
name: Identifier {
|
||||||
name: Spanned{
|
name: Spanned {
|
||||||
span: Span{left: 0, right: 0}, //todo: figure out a sane value for these
|
span: Span { left: 0, right: 0 }, //todo: figure out a sane value for these
|
||||||
value: "!".to_string(),
|
value: "!".to_string(),
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct Span {
|
pub struct Span {
|
||||||
pub left: usize,
|
pub left: usize,
|
||||||
pub right: usize
|
pub right: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
@@ -50,7 +51,6 @@ pub struct Spanned<T> {
|
|||||||
pub value: T,
|
pub value: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct FunctionTypeUsage {
|
pub struct FunctionTypeUsage {
|
||||||
pub arguments: Vec<TypeUsage>,
|
pub arguments: Vec<TypeUsage>,
|
||||||
@@ -76,31 +76,33 @@ pub enum TypeUsage {
|
|||||||
|
|
||||||
impl TypeUsage {
|
impl TypeUsage {
|
||||||
pub fn new_unknown(id_gen: &IdGenerator) -> TypeUsage {
|
pub fn new_unknown(id_gen: &IdGenerator) -> TypeUsage {
|
||||||
return TypeUsage::Unknown(UnknownTypeUsage{
|
return TypeUsage::Unknown(UnknownTypeUsage {
|
||||||
name: id_gen.next(),
|
name: id_gen.next(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_named(identifier: Identifier) -> TypeUsage {
|
pub fn new_named(identifier: Identifier) -> TypeUsage {
|
||||||
return TypeUsage::Named(NamedTypeUsage{
|
return TypeUsage::Named(NamedTypeUsage {
|
||||||
name: identifier.clone(),
|
name: identifier.clone(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_builtin(name: String) -> TypeUsage {
|
pub fn new_builtin(name: String) -> TypeUsage {
|
||||||
TypeUsage::Named(NamedTypeUsage{
|
TypeUsage::Named(NamedTypeUsage {
|
||||||
name: Identifier{
|
name: Identifier {
|
||||||
name: Spanned{
|
name: Spanned {
|
||||||
span: Span{left: 0, right: 0}, //todo: figure out a sane value for these
|
span: Span { left: 0, right: 0 }, //todo: figure out a sane value for these
|
||||||
value: name,
|
value: name,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_function(arg_count: usize, id_gen: &IdGenerator) -> TypeUsage {
|
pub fn new_function(arg_count: usize, id_gen: &IdGenerator) -> TypeUsage {
|
||||||
return TypeUsage::Function(FunctionTypeUsage{
|
return TypeUsage::Function(FunctionTypeUsage {
|
||||||
arguments: (0..arg_count).map(|_| TypeUsage::new_unknown(&id_gen)).collect(),
|
arguments: (0..arg_count)
|
||||||
|
.map(|_| TypeUsage::new_unknown(&id_gen))
|
||||||
|
.collect(),
|
||||||
return_type: Box::new(TypeUsage::new_unknown(&id_gen)),
|
return_type: Box::new(TypeUsage::new_unknown(&id_gen)),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
use std::collections::HashMap;
|
|
||||||
use std::mem;
|
|
||||||
use std::convert::TryInto;
|
|
||||||
use inkwell::builder::Builder;
|
use inkwell::builder::Builder;
|
||||||
use inkwell::context::Context;
|
use inkwell::context::Context;
|
||||||
use inkwell::module::Module;
|
use inkwell::module::Module;
|
||||||
use inkwell::values::{BasicValueEnum, FunctionValue, IntValue};
|
use inkwell::values::{BasicValueEnum, FunctionValue, IntValue};
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::convert::TryInto;
|
||||||
|
use std::mem;
|
||||||
|
|
||||||
use crate::ast;
|
use crate::ast;
|
||||||
|
|
||||||
@@ -17,28 +17,39 @@ pub struct ModuleCodeGen<'ctx> {
|
|||||||
scope: Scope<'ctx>,
|
scope: Scope<'ctx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl<'ctx> ModuleCodeGen<'ctx> {
|
impl<'ctx> ModuleCodeGen<'ctx> {
|
||||||
pub fn new(context: &'ctx Context, name: String) -> Self {
|
pub fn new(context: &'ctx Context, name: String) -> Self {
|
||||||
return ModuleCodeGen{
|
return ModuleCodeGen {
|
||||||
context: context,
|
context: context,
|
||||||
module: context.create_module(&name),
|
module: context.create_module(&name),
|
||||||
builder: context.create_builder(),
|
builder: context.create_builder(),
|
||||||
scope: Scope::new(),
|
scope: Scope::new(),
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn gen_literal_int(&mut self, literal_int: &ast::LiteralInt) -> IntValue<'ctx> {
|
pub fn gen_literal_int(&mut self, literal_int: &ast::LiteralInt) -> IntValue<'ctx> {
|
||||||
self.context.i64_type().const_int(unsafe { mem::transmute::<i64, u64>(literal_int.value) }, true)
|
self.context.i64_type().const_int(
|
||||||
|
unsafe { mem::transmute::<i64, u64>(literal_int.value) },
|
||||||
|
true,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn gen_op_expression(&mut self, scope: &Scope<'ctx>, operation: &ast::Operation) -> IntValue<'ctx> {
|
pub fn gen_op_expression(
|
||||||
|
&mut self,
|
||||||
|
scope: &Scope<'ctx>,
|
||||||
|
operation: &ast::Operation,
|
||||||
|
) -> IntValue<'ctx> {
|
||||||
let lhs_result = self.gen_expression(scope, &operation.left);
|
let lhs_result = self.gen_expression(scope, &operation.left);
|
||||||
let rhs_result = self.gen_expression(scope, &operation.right);
|
let rhs_result = self.gen_expression(scope, &operation.right);
|
||||||
self.gen_op_int(&lhs_result, &rhs_result, &operation.op)
|
self.gen_op_int(&lhs_result, &rhs_result, &operation.op)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn gen_op_int(&mut self, lhs: &IntValue<'ctx>, rhs: &IntValue<'ctx>, op: &ast::Operator) -> IntValue<'ctx> {
|
pub fn gen_op_int(
|
||||||
|
&mut self,
|
||||||
|
lhs: &IntValue<'ctx>,
|
||||||
|
rhs: &IntValue<'ctx>,
|
||||||
|
op: &ast::Operator,
|
||||||
|
) -> IntValue<'ctx> {
|
||||||
match *op {
|
match *op {
|
||||||
ast::Operator::Plus => self.builder.build_int_add(*lhs, *rhs, "add"),
|
ast::Operator::Plus => self.builder.build_int_add(*lhs, *rhs, "add"),
|
||||||
ast::Operator::Minus => self.builder.build_int_sub(*lhs, *rhs, "sub"),
|
ast::Operator::Minus => self.builder.build_int_sub(*lhs, *rhs, "sub"),
|
||||||
@@ -47,28 +58,40 @@ impl<'ctx> ModuleCodeGen<'ctx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn gen_expression(&mut self, scope: &Scope<'ctx>, expression: &Box<ast::Expression>) -> IntValue<'ctx> {
|
pub fn gen_expression(
|
||||||
|
&mut self,
|
||||||
|
scope: &Scope<'ctx>,
|
||||||
|
expression: &Box<ast::Expression>,
|
||||||
|
) -> IntValue<'ctx> {
|
||||||
match &**expression {
|
match &**expression {
|
||||||
ast::Expression::LiteralInt(literal_int) => self.gen_literal_int(&literal_int),
|
ast::Expression::LiteralInt(literal_int) => self.gen_literal_int(&literal_int),
|
||||||
ast::Expression::Identifier(identifier) => {
|
ast::Expression::Identifier(identifier) => match scope[&identifier.name] {
|
||||||
match scope[&identifier.name] {
|
BasicValueEnum::IntValue(value) => value,
|
||||||
BasicValueEnum::IntValue(value) => value,
|
_ => panic!("function returned type other than int, no types yet"),
|
||||||
_ => panic!("function returned type other than int, no types yet"),
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
ast::Expression::FunctionCall(function_call) => self.gen_function_call(scope, &function_call),
|
ast::Expression::FunctionCall(function_call) => {
|
||||||
|
self.gen_function_call(scope, &function_call)
|
||||||
|
}
|
||||||
ast::Expression::Op(operation) => self.gen_op_expression(scope, &operation),
|
ast::Expression::Op(operation) => self.gen_op_expression(scope, &operation),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn gen_function_call(&mut self, scope: &Scope<'ctx>, function_call: &ast::FunctionCall) -> IntValue<'ctx> {
|
pub fn gen_function_call(
|
||||||
|
&mut self,
|
||||||
|
scope: &Scope<'ctx>,
|
||||||
|
function_call: &ast::FunctionCall,
|
||||||
|
) -> IntValue<'ctx> {
|
||||||
let fn_value = self.module.get_function(&function_call.name.name).unwrap();
|
let fn_value = self.module.get_function(&function_call.name.name).unwrap();
|
||||||
let mut arguments = Vec::new();
|
let mut arguments = Vec::new();
|
||||||
for expression in (&function_call.arguments).into_iter() {
|
for expression in (&function_call.arguments).into_iter() {
|
||||||
arguments.push(BasicValueEnum::IntValue(self.gen_expression(scope, &expression)));
|
arguments.push(BasicValueEnum::IntValue(
|
||||||
|
self.gen_expression(scope, &expression),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = self.builder.build_call(fn_value, &arguments, &function_call.name.name)
|
let result = self
|
||||||
|
.builder
|
||||||
|
.build_call(fn_value, &arguments, &function_call.name.name)
|
||||||
.try_as_basic_value()
|
.try_as_basic_value()
|
||||||
.left()
|
.left()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@@ -100,7 +123,10 @@ impl<'ctx> ModuleCodeGen<'ctx> {
|
|||||||
|
|
||||||
let mut scope = self.scope.clone();
|
let mut scope = self.scope.clone();
|
||||||
for (i, param) in (&function.arguments).into_iter().enumerate() {
|
for (i, param) in (&function.arguments).into_iter().enumerate() {
|
||||||
scope.insert(param.name.name.to_string(), fn_value.get_nth_param(i.try_into().unwrap()).unwrap());
|
scope.insert(
|
||||||
|
param.name.name.to_string(),
|
||||||
|
fn_value.get_nth_param(i.try_into().unwrap()).unwrap(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
let body = &function.block;
|
let body = &function.block;
|
||||||
let return_value = self.gen_expression(&scope, &body.expression);
|
let return_value = self.gen_expression(&scope, &body.expression);
|
||||||
|
|||||||
132
src/main.rs
132
src/main.rs
@@ -2,7 +2,8 @@
|
|||||||
mod ast;
|
mod ast;
|
||||||
mod type_alias_resolution;
|
mod type_alias_resolution;
|
||||||
mod type_checking;
|
mod type_checking;
|
||||||
#[macro_use] extern crate lalrpop_util;
|
#[macro_use]
|
||||||
|
extern crate lalrpop_util;
|
||||||
|
|
||||||
lalrpop_mod!(pub grammar); // synthesized by LALRPOP
|
lalrpop_mod!(pub grammar); // synthesized by LALRPOP
|
||||||
|
|
||||||
@@ -11,42 +12,54 @@ use std::io::Write;
|
|||||||
// mod compiler;
|
// mod compiler;
|
||||||
// use inkwell::context::Context;
|
// use inkwell::context::Context;
|
||||||
extern crate clap;
|
extern crate clap;
|
||||||
use clap::{Arg, App};
|
use clap::{App, Arg};
|
||||||
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let matches = App::new("Boring Language Compiler")
|
let matches = App::new("Boring Language Compiler")
|
||||||
.version("0.0.1")
|
.version("0.0.1")
|
||||||
.author("Andrew Segavac")
|
.author("Andrew Segavac")
|
||||||
.about("Compiles boring language files to LLVM IR.")
|
.about("Compiles boring language files to LLVM IR.")
|
||||||
.arg(Arg::with_name("OUTPUT")
|
.arg(
|
||||||
.short("o")
|
Arg::with_name("OUTPUT")
|
||||||
.long("out")
|
.short("o")
|
||||||
.value_name("OUTOUT")
|
.long("out")
|
||||||
.help("Sets an output file")
|
.value_name("OUTOUT")
|
||||||
.takes_value(true))
|
.help("Sets an output file")
|
||||||
.arg(Arg::with_name("INPUT")
|
.takes_value(true),
|
||||||
.help("Sets the input file")
|
)
|
||||||
.required(true)
|
.arg(
|
||||||
.index(1))
|
Arg::with_name("INPUT")
|
||||||
.arg(Arg::with_name("v")
|
.help("Sets the input file")
|
||||||
.short("v")
|
.required(true)
|
||||||
.multiple(true)
|
.index(1),
|
||||||
.help("Sets the level of verbosity"))
|
)
|
||||||
.get_matches();
|
.arg(
|
||||||
|
Arg::with_name("v")
|
||||||
|
.short("v")
|
||||||
|
.multiple(true)
|
||||||
|
.help("Sets the level of verbosity"),
|
||||||
|
)
|
||||||
|
.get_matches();
|
||||||
let input = matches.value_of("INPUT").unwrap();
|
let input = matches.value_of("INPUT").unwrap();
|
||||||
|
|
||||||
let default_output = input.rsplitn(2, ".").collect::<Vec<&str>>().last().unwrap().clone();
|
let default_output = input
|
||||||
|
.rsplitn(2, ".")
|
||||||
|
.collect::<Vec<&str>>()
|
||||||
|
.last()
|
||||||
|
.unwrap()
|
||||||
|
.clone();
|
||||||
let output = matches.value_of("OUTPUT").unwrap_or(default_output);
|
let output = matches.value_of("OUTPUT").unwrap_or(default_output);
|
||||||
|
|
||||||
let contents = fs::read_to_string(input).expect("input file not found");
|
let contents = fs::read_to_string(input).expect("input file not found");
|
||||||
let unknown_id_gen = ast::IdGenerator::new();
|
let unknown_id_gen = ast::IdGenerator::new();
|
||||||
let module_ast = grammar::ModuleParser::new().parse(&unknown_id_gen, &contents).unwrap(); //TODO: convert to error
|
let module_ast = grammar::ModuleParser::new()
|
||||||
|
.parse(&unknown_id_gen, &contents)
|
||||||
|
.unwrap(); //TODO: convert to error
|
||||||
println!("ast: {:#?}", &module_ast);
|
println!("ast: {:#?}", &module_ast);
|
||||||
let alias_resolver = type_alias_resolution::TypeAliasResolver{};
|
let alias_resolver = type_alias_resolution::TypeAliasResolver {};
|
||||||
let resolved_ast = alias_resolver.with_module(&module_ast);
|
let resolved_ast = alias_resolver.with_module(&module_ast);
|
||||||
println!("resolved ast: {:#?}", &resolved_ast);
|
println!("resolved ast: {:#?}", &resolved_ast);
|
||||||
let type_checker = type_checking::TypeChecker{};
|
let type_checker = type_checking::TypeChecker {};
|
||||||
let (checked_ast, subst) = type_checker.with_module(&resolved_ast);
|
let (checked_ast, subst) = type_checker.with_module(&resolved_ast);
|
||||||
println!("checked ast: {:#?}", &checked_ast);
|
println!("checked ast: {:#?}", &checked_ast);
|
||||||
println!("substitutions: {:#?}", &subst);
|
println!("substitutions: {:#?}", &subst);
|
||||||
@@ -59,37 +72,70 @@ fn main() {
|
|||||||
// f.write_all(code_gen.dump().as_bytes()).expect("Unable to write data");
|
// f.write_all(code_gen.dump().as_bytes()).expect("Unable to write data");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn grammar() {
|
fn grammar() {
|
||||||
let id_gen = ast::IdGenerator::new();
|
let id_gen = ast::IdGenerator::new();
|
||||||
assert!(grammar::LiteralIntParser::new().parse(&id_gen, "22").is_ok());
|
assert!(grammar::LiteralIntParser::new()
|
||||||
assert!(grammar::IdentifierParser::new().parse(&id_gen, "foo").is_ok());
|
.parse(&id_gen, "22")
|
||||||
assert!(grammar::LiteralIntParser::new().parse(&id_gen, "2a").is_err());
|
.is_ok());
|
||||||
|
assert!(grammar::IdentifierParser::new()
|
||||||
|
.parse(&id_gen, "foo")
|
||||||
|
.is_ok());
|
||||||
|
assert!(grammar::LiteralIntParser::new()
|
||||||
|
.parse(&id_gen, "2a")
|
||||||
|
.is_err());
|
||||||
|
|
||||||
assert!(grammar::TermParser::new().parse(&id_gen, "22").is_ok());
|
assert!(grammar::TermParser::new().parse(&id_gen, "22").is_ok());
|
||||||
assert!(grammar::TermParser::new().parse(&id_gen, "foo").is_ok());
|
assert!(grammar::TermParser::new().parse(&id_gen, "foo").is_ok());
|
||||||
|
|
||||||
assert!(grammar::ExpressionParser::new().parse(&id_gen, "22 * foo").is_ok());
|
assert!(grammar::ExpressionParser::new()
|
||||||
assert!(grammar::ExpressionParser::new().parse(&id_gen, "22 * 33").is_ok());
|
.parse(&id_gen, "22 * foo")
|
||||||
assert!(grammar::ExpressionParser::new().parse(&id_gen, "(22 * 33) + 24").is_ok());
|
.is_ok());
|
||||||
|
assert!(grammar::ExpressionParser::new()
|
||||||
|
.parse(&id_gen, "22 * 33")
|
||||||
|
.is_ok());
|
||||||
|
assert!(grammar::ExpressionParser::new()
|
||||||
|
.parse(&id_gen, "(22 * 33) + 24")
|
||||||
|
.is_ok());
|
||||||
|
|
||||||
assert!(grammar::BlockParser::new().parse(&id_gen, "{ (22 * 33) + 24 }").is_ok());
|
assert!(grammar::BlockParser::new()
|
||||||
assert!(grammar::BlockParser::new().parse(&id_gen, "{ (22 * 33) + 24; 25 }").is_ok());
|
.parse(&id_gen, "{ (22 * 33) + 24 }")
|
||||||
|
.is_ok());
|
||||||
|
assert!(grammar::BlockParser::new()
|
||||||
|
.parse(&id_gen, "{ (22 * 33) + 24; 25 }")
|
||||||
|
.is_ok());
|
||||||
// assert!(grammar::BlockParser::new().parse("{ (22 * 33) + 24\n 24 }").is_ok());
|
// assert!(grammar::BlockParser::new().parse("{ (22 * 33) + 24\n 24 }").is_ok());
|
||||||
assert!(grammar::BlockParser::new().parse(&id_gen, "{ }").is_ok());
|
assert!(grammar::BlockParser::new().parse(&id_gen, "{ }").is_ok());
|
||||||
|
|
||||||
assert!(grammar::VariableDeclarationParser::new().parse(&id_gen, "foo: Int32").is_ok());
|
assert!(grammar::VariableDeclarationParser::new()
|
||||||
assert!(grammar::VariableDeclarationParser::new().parse(&id_gen, "foo").is_err());
|
.parse(&id_gen, "foo: Int32")
|
||||||
assert!(grammar::VariableDeclarationParser::new().parse(&id_gen, "1234").is_err());
|
.is_ok());
|
||||||
|
assert!(grammar::VariableDeclarationParser::new()
|
||||||
|
.parse(&id_gen, "foo")
|
||||||
|
.is_err());
|
||||||
|
assert!(grammar::VariableDeclarationParser::new()
|
||||||
|
.parse(&id_gen, "1234")
|
||||||
|
.is_err());
|
||||||
|
|
||||||
assert!(grammar::FunctionParser::new().parse(&id_gen, "fn add(a: Int32, b: Int32): Int32 { a + b }").is_ok());
|
assert!(grammar::FunctionParser::new()
|
||||||
assert!(grammar::FunctionParser::new().parse(&id_gen, "fn random_dice_roll(): Int32 { 4 }").is_ok());
|
.parse(&id_gen, "fn add(a: Int32, b: Int32): Int32 { a + b }")
|
||||||
assert!(grammar::FunctionParser::new().parse(&id_gen, "fn add(a: Int32, b: Int32): Int32 { a + }").is_err());
|
.is_ok());
|
||||||
assert!(grammar::FunctionParser::new().parse(&id_gen, "fn add(a: Int32, b: Int32): Int32").is_err());
|
assert!(grammar::FunctionParser::new()
|
||||||
|
.parse(&id_gen, "fn random_dice_roll(): Int32 { 4 }")
|
||||||
|
.is_ok());
|
||||||
|
assert!(grammar::FunctionParser::new()
|
||||||
|
.parse(&id_gen, "fn add(a: Int32, b: Int32): Int32 { a + }")
|
||||||
|
.is_err());
|
||||||
|
assert!(grammar::FunctionParser::new()
|
||||||
|
.parse(&id_gen, "fn add(a: Int32, b: Int32): Int32")
|
||||||
|
.is_err());
|
||||||
|
|
||||||
assert!(grammar::FunctionCallParser::new().parse(&id_gen, "foo(1, 2)").is_ok());
|
assert!(grammar::FunctionCallParser::new()
|
||||||
|
.parse(&id_gen, "foo(1, 2)")
|
||||||
|
.is_ok());
|
||||||
|
|
||||||
assert!(grammar::ModuleParser::new().parse(&id_gen, "fn add(a: Int32, b: Int32): Int32 { a + b }").is_ok());
|
assert!(grammar::ModuleParser::new()
|
||||||
|
.parse(&id_gen, "fn add(a: Int32, b: Int32): Int32 { a + b }")
|
||||||
|
.is_ok());
|
||||||
assert!(grammar::ModuleParser::new().parse(&id_gen, "fn add(a: Int32, b: Int32): Int32 { a + b } fn subtract(a: Int32, b: Int32): Int32 { a - b }").is_ok());
|
assert!(grammar::ModuleParser::new().parse(&id_gen, "fn add(a: Int32, b: Int32): Int32 { a + b } fn subtract(a: Int32, b: Int32): Int32 { a - b }").is_ok());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
use crate::ast;
|
use crate::ast;
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
struct Context {
|
struct Context {
|
||||||
pub type_aliases: Vec<ast::AliasTypeDeclaration>,
|
pub type_aliases: Vec<ast::AliasTypeDeclaration>,
|
||||||
@@ -20,7 +19,7 @@ fn resolve_type(ctx: &Context, type_: &ast::NamedTypeUsage) -> ast::TypeUsage {
|
|||||||
result = alias.replaces.clone();
|
result = alias.replaces.clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
_ => break,
|
_ => break,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -31,16 +30,20 @@ fn process_type(ctx: &Context, type_: &ast::TypeUsage) -> ast::TypeUsage {
|
|||||||
match type_ {
|
match type_ {
|
||||||
ast::TypeUsage::Named(named) => {
|
ast::TypeUsage::Named(named) => {
|
||||||
return resolve_type(ctx, named);
|
return resolve_type(ctx, named);
|
||||||
},
|
}
|
||||||
ast::TypeUsage::Function(function) => {
|
ast::TypeUsage::Function(function) => {
|
||||||
return ast::TypeUsage::Function(ast::FunctionTypeUsage{
|
return ast::TypeUsage::Function(ast::FunctionTypeUsage {
|
||||||
arguments: function.arguments.iter().map(|a|{process_type(ctx, &a.clone())}).collect(),
|
arguments: function
|
||||||
|
.arguments
|
||||||
|
.iter()
|
||||||
|
.map(|a| process_type(ctx, &a.clone()))
|
||||||
|
.collect(),
|
||||||
return_type: Box::new(process_type(ctx, &function.return_type.clone())),
|
return_type: Box::new(process_type(ctx, &function.return_type.clone())),
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
ast::TypeUsage::Unknown(unknown) => {
|
ast::TypeUsage::Unknown(unknown) => {
|
||||||
return ast::TypeUsage::Unknown(unknown.clone());
|
return ast::TypeUsage::Unknown(unknown.clone());
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,98 +51,124 @@ pub struct TypeAliasResolver {}
|
|||||||
|
|
||||||
impl TypeAliasResolver {
|
impl TypeAliasResolver {
|
||||||
pub fn with_module(self: &Self, module: &ast::Module) -> ast::Module {
|
pub fn with_module(self: &Self, module: &ast::Module) -> ast::Module {
|
||||||
let mut ctx = Context{
|
let mut ctx = Context {
|
||||||
type_aliases: vec!(),
|
type_aliases: vec![],
|
||||||
};
|
};
|
||||||
for item in module.items.iter() {
|
for item in module.items.iter() {
|
||||||
match item {
|
match item {
|
||||||
ast::ModuleItem::TypeDeclaration(ast::TypeDeclaration::Alias(alias)) => {
|
ast::ModuleItem::TypeDeclaration(ast::TypeDeclaration::Alias(alias)) => {
|
||||||
ctx.type_aliases.push(alias.clone());
|
ctx.type_aliases.push(alias.clone());
|
||||||
},
|
}
|
||||||
_ => {},
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ast::Module{
|
return ast::Module {
|
||||||
items: module.items.iter().map(|item|{
|
items: module
|
||||||
match item {
|
.items
|
||||||
|
.iter()
|
||||||
|
.map(|item| match item {
|
||||||
ast::ModuleItem::Function(function) => {
|
ast::ModuleItem::Function(function) => {
|
||||||
ast::ModuleItem::Function(self.with_function(&ctx, function))
|
ast::ModuleItem::Function(self.with_function(&ctx, function))
|
||||||
},
|
}
|
||||||
ast::ModuleItem::TypeDeclaration(type_declaration) => {
|
ast::ModuleItem::TypeDeclaration(type_declaration) => {
|
||||||
ast::ModuleItem::TypeDeclaration(self.with_type_declaration(&ctx, type_declaration))
|
ast::ModuleItem::TypeDeclaration(
|
||||||
},
|
self.with_type_declaration(&ctx, type_declaration),
|
||||||
|
)
|
||||||
|
}
|
||||||
ast::ModuleItem::Impl(impl_) => {
|
ast::ModuleItem::Impl(impl_) => {
|
||||||
ast::ModuleItem::Impl(self.with_impl(&ctx, impl_))
|
ast::ModuleItem::Impl(self.with_impl(&ctx, impl_))
|
||||||
},
|
}
|
||||||
}
|
})
|
||||||
}).collect()
|
.collect(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_function(self: &Self, ctx: &Context, function: &ast::Function) -> ast::Function {
|
fn with_function(self: &Self, ctx: &Context, function: &ast::Function) -> ast::Function {
|
||||||
return ast::Function{
|
return ast::Function {
|
||||||
declaration: ast::FunctionDeclaration{
|
declaration: ast::FunctionDeclaration {
|
||||||
name: function.declaration.name.clone(),
|
name: function.declaration.name.clone(),
|
||||||
arguments: function.declaration.arguments.iter().map(|arg| {
|
arguments: function
|
||||||
ast::VariableDeclaration{name: arg.name.clone(), type_: process_type(ctx, &arg.type_)}
|
.declaration
|
||||||
}).collect(),
|
.arguments
|
||||||
|
.iter()
|
||||||
|
.map(|arg| ast::VariableDeclaration {
|
||||||
|
name: arg.name.clone(),
|
||||||
|
type_: process_type(ctx, &arg.type_),
|
||||||
|
})
|
||||||
|
.collect(),
|
||||||
return_type: process_type(ctx, &function.declaration.return_type),
|
return_type: process_type(ctx, &function.declaration.return_type),
|
||||||
},
|
},
|
||||||
block: self.with_block(ctx, &function.block),
|
block: self.with_block(ctx, &function.block),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_type_declaration(self: &Self, ctx: &Context, type_declaration: &ast::TypeDeclaration) -> ast::TypeDeclaration {
|
fn with_type_declaration(
|
||||||
|
self: &Self,
|
||||||
|
ctx: &Context,
|
||||||
|
type_declaration: &ast::TypeDeclaration,
|
||||||
|
) -> ast::TypeDeclaration {
|
||||||
match type_declaration {
|
match type_declaration {
|
||||||
ast::TypeDeclaration::Struct(struct_) => {
|
ast::TypeDeclaration::Struct(struct_) => {
|
||||||
return ast::TypeDeclaration::Struct(self.with_struct_declaration(ctx, struct_));
|
return ast::TypeDeclaration::Struct(self.with_struct_declaration(ctx, struct_));
|
||||||
},
|
}
|
||||||
ast::TypeDeclaration::Primitive(primitive) => {
|
ast::TypeDeclaration::Primitive(primitive) => {
|
||||||
return ast::TypeDeclaration::Primitive(primitive.clone());
|
return ast::TypeDeclaration::Primitive(primitive.clone());
|
||||||
},
|
}
|
||||||
ast::TypeDeclaration::Alias(alias) => {
|
ast::TypeDeclaration::Alias(alias) => {
|
||||||
return ast::TypeDeclaration::Alias(alias.clone());
|
return ast::TypeDeclaration::Alias(alias.clone());
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_struct_declaration(self: &Self, ctx: &Context, struct_: &ast::StructTypeDeclaration) -> ast::StructTypeDeclaration {
|
fn with_struct_declaration(
|
||||||
return ast::StructTypeDeclaration{
|
self: &Self,
|
||||||
|
ctx: &Context,
|
||||||
|
struct_: &ast::StructTypeDeclaration,
|
||||||
|
) -> ast::StructTypeDeclaration {
|
||||||
|
return ast::StructTypeDeclaration {
|
||||||
name: struct_.name.clone(),
|
name: struct_.name.clone(),
|
||||||
fields: struct_.fields.iter().map(|field|{
|
fields: struct_
|
||||||
ast::StructField{
|
.fields
|
||||||
|
.iter()
|
||||||
|
.map(|field| ast::StructField {
|
||||||
name: field.name.clone(),
|
name: field.name.clone(),
|
||||||
type_: process_type(ctx, &field.type_),
|
type_: process_type(ctx, &field.type_),
|
||||||
}
|
})
|
||||||
}).collect(),
|
.collect(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_impl(self: &Self, ctx: &Context, impl_: &ast::Impl) -> ast::Impl {
|
fn with_impl(self: &Self, ctx: &Context, impl_: &ast::Impl) -> ast::Impl {
|
||||||
let mut impl_ctx = ctx.clone();
|
let mut impl_ctx = ctx.clone();
|
||||||
impl_ctx.type_aliases.push(ast::AliasTypeDeclaration{
|
impl_ctx.type_aliases.push(ast::AliasTypeDeclaration {
|
||||||
name: ast::Identifier{
|
name: ast::Identifier {
|
||||||
name: ast::Spanned{
|
name: ast::Spanned {
|
||||||
span: ast::Span{left: 0, right: 0}, //todo: figure out a sane value for these
|
span: ast::Span { left: 0, right: 0 }, //todo: figure out a sane value for these
|
||||||
value: "Self".to_string(),
|
value: "Self".to_string(),
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
replaces: ast::TypeUsage::Named(ast::NamedTypeUsage{name: impl_.struct_name.clone()})
|
replaces: ast::TypeUsage::Named(ast::NamedTypeUsage {
|
||||||
|
name: impl_.struct_name.clone(),
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
return ast::Impl{
|
return ast::Impl {
|
||||||
struct_name: impl_.struct_name.clone(),
|
struct_name: impl_.struct_name.clone(),
|
||||||
functions: impl_.functions.iter().map(|f|{
|
functions: impl_
|
||||||
self.with_function(&impl_ctx, f)
|
.functions
|
||||||
}).collect(),
|
.iter()
|
||||||
|
.map(|f| self.with_function(&impl_ctx, f))
|
||||||
|
.collect(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_block(self: &Self, ctx: &Context, block: &ast::Block) -> ast::Block {
|
fn with_block(self: &Self, ctx: &Context, block: &ast::Block) -> ast::Block {
|
||||||
return ast::Block{
|
return ast::Block {
|
||||||
statements: block.statements.iter().map(|s| {
|
statements: block
|
||||||
self.with_statement(ctx, s)
|
.statements
|
||||||
}).collect(),
|
.iter()
|
||||||
|
.map(|s| self.with_statement(ctx, s))
|
||||||
|
.collect(),
|
||||||
type_: process_type(ctx, &block.type_),
|
type_: process_type(ctx, &block.type_),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -148,115 +177,142 @@ impl TypeAliasResolver {
|
|||||||
match statement {
|
match statement {
|
||||||
ast::Statement::Return(return_statement) => {
|
ast::Statement::Return(return_statement) => {
|
||||||
return ast::Statement::Return(self.with_return_statement(ctx, return_statement));
|
return ast::Statement::Return(self.with_return_statement(ctx, return_statement));
|
||||||
},
|
}
|
||||||
ast::Statement::Let(let_statement) => {
|
ast::Statement::Let(let_statement) => {
|
||||||
return ast::Statement::Let(self.with_let_statement(ctx, let_statement));
|
return ast::Statement::Let(self.with_let_statement(ctx, let_statement));
|
||||||
},
|
}
|
||||||
ast::Statement::Assignment(assignment_statement) => {
|
ast::Statement::Assignment(assignment_statement) => {
|
||||||
return ast::Statement::Assignment(self.with_assignment_statement(ctx, assignment_statement));
|
return ast::Statement::Assignment(
|
||||||
},
|
self.with_assignment_statement(ctx, assignment_statement),
|
||||||
|
);
|
||||||
|
}
|
||||||
ast::Statement::Expression(expression) => {
|
ast::Statement::Expression(expression) => {
|
||||||
return ast::Statement::Expression(self.with_expression(ctx, expression));
|
return ast::Statement::Expression(self.with_expression(ctx, expression));
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_return_statement(self: &Self, ctx: &Context, statement: &ast::ReturnStatement) -> ast::ReturnStatement {
|
fn with_return_statement(
|
||||||
return ast::ReturnStatement{
|
self: &Self,
|
||||||
|
ctx: &Context,
|
||||||
|
statement: &ast::ReturnStatement,
|
||||||
|
) -> ast::ReturnStatement {
|
||||||
|
return ast::ReturnStatement {
|
||||||
source: self.with_expression(ctx, &statement.source),
|
source: self.with_expression(ctx, &statement.source),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_let_statement(self: &Self, ctx: &Context, statement: &ast::LetStatement) -> ast::LetStatement {
|
fn with_let_statement(
|
||||||
return ast::LetStatement{
|
self: &Self,
|
||||||
|
ctx: &Context,
|
||||||
|
statement: &ast::LetStatement,
|
||||||
|
) -> ast::LetStatement {
|
||||||
|
return ast::LetStatement {
|
||||||
variable_name: statement.variable_name.clone(),
|
variable_name: statement.variable_name.clone(),
|
||||||
expression: self.with_expression(ctx, &statement.expression),
|
expression: self.with_expression(ctx, &statement.expression),
|
||||||
type_: process_type(ctx, &statement.type_),
|
type_: process_type(ctx, &statement.type_),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_assignment_statement(self: &Self, ctx: &Context, statement: &ast::AssignmentStatement) -> ast::AssignmentStatement {
|
fn with_assignment_statement(
|
||||||
return ast::AssignmentStatement{
|
self: &Self,
|
||||||
|
ctx: &Context,
|
||||||
|
statement: &ast::AssignmentStatement,
|
||||||
|
) -> ast::AssignmentStatement {
|
||||||
|
return ast::AssignmentStatement {
|
||||||
source: match &statement.source {
|
source: match &statement.source {
|
||||||
ast::AssignmentTarget::Variable(variable) => {
|
ast::AssignmentTarget::Variable(variable) => {
|
||||||
ast::AssignmentTarget::Variable(ast::VariableUsage{
|
ast::AssignmentTarget::Variable(ast::VariableUsage {
|
||||||
name: variable.name.clone(),
|
name: variable.name.clone(),
|
||||||
type_: process_type(ctx, &variable.type_),
|
type_: process_type(ctx, &variable.type_),
|
||||||
})
|
})
|
||||||
},
|
}
|
||||||
ast::AssignmentTarget::StructAttr(struct_attr) => {
|
ast::AssignmentTarget::StructAttr(struct_attr) => {
|
||||||
ast::AssignmentTarget::StructAttr(ast::StructGetter{
|
ast::AssignmentTarget::StructAttr(ast::StructGetter {
|
||||||
source: self.with_expression(ctx, &struct_attr.source),
|
source: self.with_expression(ctx, &struct_attr.source),
|
||||||
attribute: struct_attr.attribute.clone(),
|
attribute: struct_attr.attribute.clone(),
|
||||||
type_: process_type(ctx, &struct_attr.type_)
|
type_: process_type(ctx, &struct_attr.type_),
|
||||||
})
|
})
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
expression: self.with_expression(ctx, &statement.expression),
|
expression: self.with_expression(ctx, &statement.expression),
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_expression(self: &Self, ctx: &Context, expression: &ast::Expression) -> ast::Expression {
|
fn with_expression(
|
||||||
return ast::Expression{
|
self: &Self,
|
||||||
|
ctx: &Context,
|
||||||
|
expression: &ast::Expression,
|
||||||
|
) -> ast::Expression {
|
||||||
|
return ast::Expression {
|
||||||
subexpression: Box::new(match &*expression.subexpression {
|
subexpression: Box::new(match &*expression.subexpression {
|
||||||
ast::Subexpression::LiteralInt(literal_int) => {
|
ast::Subexpression::LiteralInt(literal_int) => {
|
||||||
ast::Subexpression::LiteralInt(ast::LiteralInt{
|
ast::Subexpression::LiteralInt(ast::LiteralInt {
|
||||||
value: literal_int.value.clone(),
|
value: literal_int.value.clone(),
|
||||||
type_: process_type(ctx, &literal_int.type_),
|
type_: process_type(ctx, &literal_int.type_),
|
||||||
})
|
})
|
||||||
},
|
}
|
||||||
ast::Subexpression::LiteralFloat(literal_float) => {
|
ast::Subexpression::LiteralFloat(literal_float) => {
|
||||||
ast::Subexpression::LiteralFloat(ast::LiteralFloat{
|
ast::Subexpression::LiteralFloat(ast::LiteralFloat {
|
||||||
value: literal_float.value.clone(),
|
value: literal_float.value.clone(),
|
||||||
type_: process_type(ctx, &literal_float.type_),
|
type_: process_type(ctx, &literal_float.type_),
|
||||||
})
|
})
|
||||||
},
|
}
|
||||||
ast::Subexpression::LiteralStruct(literal_struct) => {
|
ast::Subexpression::LiteralStruct(literal_struct) => {
|
||||||
let result = resolve_type(ctx, &ast::NamedTypeUsage{name: literal_struct.name.clone()});
|
let result = resolve_type(
|
||||||
|
ctx,
|
||||||
|
&ast::NamedTypeUsage {
|
||||||
|
name: literal_struct.name.clone(),
|
||||||
|
},
|
||||||
|
);
|
||||||
let new_name = match &result {
|
let new_name = match &result {
|
||||||
ast::TypeUsage::Named(named) => { named.name.clone() },
|
ast::TypeUsage::Named(named) => named.name.clone(),
|
||||||
_ => panic!("LiteralStruct resolved to non-named-type"),
|
_ => panic!("LiteralStruct resolved to non-named-type"),
|
||||||
};
|
};
|
||||||
ast::Subexpression::LiteralStruct(ast::LiteralStruct{
|
ast::Subexpression::LiteralStruct(ast::LiteralStruct {
|
||||||
name: new_name.clone(),
|
name: new_name.clone(),
|
||||||
fields: literal_struct.fields.iter().map(|field|{
|
fields: literal_struct
|
||||||
(field.0.clone(), self.with_expression(ctx, &field.1))
|
.fields
|
||||||
}).collect(),
|
.iter()
|
||||||
|
.map(|field| (field.0.clone(), self.with_expression(ctx, &field.1)))
|
||||||
|
.collect(),
|
||||||
type_: process_type(ctx, &literal_struct.type_),
|
type_: process_type(ctx, &literal_struct.type_),
|
||||||
})
|
})
|
||||||
},
|
}
|
||||||
ast::Subexpression::FunctionCall(function_call) => {
|
ast::Subexpression::FunctionCall(function_call) => {
|
||||||
ast::Subexpression::FunctionCall(ast::FunctionCall{
|
ast::Subexpression::FunctionCall(ast::FunctionCall {
|
||||||
source: self.with_expression(ctx, &function_call.source),
|
source: self.with_expression(ctx, &function_call.source),
|
||||||
arguments: function_call.arguments.iter().map(|arg| {self.with_expression(ctx, arg)}).collect(),
|
arguments: function_call
|
||||||
type_: process_type(ctx, &function_call.type_)
|
.arguments
|
||||||
|
.iter()
|
||||||
|
.map(|arg| self.with_expression(ctx, arg))
|
||||||
|
.collect(),
|
||||||
|
type_: process_type(ctx, &function_call.type_),
|
||||||
})
|
})
|
||||||
},
|
}
|
||||||
ast::Subexpression::VariableUsage(variable_usage) => {
|
ast::Subexpression::VariableUsage(variable_usage) => {
|
||||||
ast::Subexpression::VariableUsage(ast::VariableUsage{
|
ast::Subexpression::VariableUsage(ast::VariableUsage {
|
||||||
name: variable_usage.name.clone(),
|
name: variable_usage.name.clone(),
|
||||||
type_: process_type(ctx, &variable_usage.type_)
|
type_: process_type(ctx, &variable_usage.type_),
|
||||||
})
|
})
|
||||||
},
|
}
|
||||||
ast::Subexpression::StructGetter(struct_getter) => {
|
ast::Subexpression::StructGetter(struct_getter) => {
|
||||||
ast::Subexpression::StructGetter(ast::StructGetter{
|
ast::Subexpression::StructGetter(ast::StructGetter {
|
||||||
source: self.with_expression(ctx, &struct_getter.source),
|
source: self.with_expression(ctx, &struct_getter.source),
|
||||||
attribute: struct_getter.attribute.clone(),
|
attribute: struct_getter.attribute.clone(),
|
||||||
type_: process_type(ctx, &struct_getter.type_),
|
type_: process_type(ctx, &struct_getter.type_),
|
||||||
})
|
})
|
||||||
},
|
}
|
||||||
ast::Subexpression::Block(block) => {
|
ast::Subexpression::Block(block) => {
|
||||||
ast::Subexpression::Block(self.with_block(ctx, &block))
|
ast::Subexpression::Block(self.with_block(ctx, &block))
|
||||||
},
|
}
|
||||||
ast::Subexpression::Op(op) => {
|
ast::Subexpression::Op(op) => ast::Subexpression::Op(ast::Operation {
|
||||||
ast::Subexpression::Op(ast::Operation{
|
left: self.with_expression(ctx, &op.left),
|
||||||
left: self.with_expression(ctx, &op.left),
|
op: op.op.clone(),
|
||||||
op: op.op.clone(),
|
right: self.with_expression(ctx, &op.right),
|
||||||
right: self.with_expression(ctx, &op.right),
|
}),
|
||||||
})
|
|
||||||
},
|
|
||||||
}),
|
}),
|
||||||
type_: process_type(ctx, &expression.type_),
|
type_: process_type(ctx, &expression.type_),
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,6 @@ pub enum Signedness {
|
|||||||
Unsigned,
|
Unsigned,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
|
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
|
||||||
pub enum IntBitness {
|
pub enum IntBitness {
|
||||||
X8,
|
X8,
|
||||||
@@ -14,7 +13,6 @@ pub enum IntBitness {
|
|||||||
X128,
|
X128,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
|
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
|
||||||
pub enum FloatBitness {
|
pub enum FloatBitness {
|
||||||
X32,
|
X32,
|
||||||
@@ -22,14 +20,12 @@ pub enum FloatBitness {
|
|||||||
X128,
|
X128,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Clone, Eq, PartialEq, Hash)]
|
#[derive(Clone, Eq, PartialEq, Hash)]
|
||||||
pub struct IntTypeDef {
|
pub struct IntTypeDef {
|
||||||
pub signedness: Signedness,
|
pub signedness: Signedness,
|
||||||
pub bitness: IntBitness,
|
pub bitness: IntBitness,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct FloatTypeDef {
|
pub struct FloatTypeDef {
|
||||||
pub bitness: FloatBitness,
|
pub bitness: FloatBitness,
|
||||||
@@ -41,7 +37,6 @@ pub struct FunctionTypeDef {
|
|||||||
pub return_type: Box<Type>,
|
pub return_type: Box<Type>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||||
pub enum Type {
|
pub enum Type {
|
||||||
Bool,
|
Bool,
|
||||||
@@ -55,7 +50,6 @@ pub enum Type {
|
|||||||
// Never,
|
// Never,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Used for places where type info may or may not be solved.
|
/// Used for places where type info may or may not be solved.
|
||||||
#[derive(Clone, Eq, PartialEq, Hash)]
|
#[derive(Clone, Eq, PartialEq, Hash)]
|
||||||
pub enum SpecifiedType {
|
pub enum SpecifiedType {
|
||||||
|
|||||||
Reference in New Issue
Block a user