diff --git a/core_lang/src/semantic_analysis/ast_node/declaration.rs b/core_lang/src/semantic_analysis/ast_node/declaration.rs index 27e7e1a6204..f7551ae013e 100644 --- a/core_lang/src/semantic_analysis/ast_node/declaration.rs +++ b/core_lang/src/semantic_analysis/ast_node/declaration.rs @@ -411,3 +411,24 @@ impl<'sc> TypedFunctionDeclaration<'sc> { ) } } + +impl<'sc> TypedTraitFn<'sc> { + /// This function is used in trait declarations to insert "placeholder" functions + /// in the methods. This allows the methods to use functions declared in the + /// interface surface. + pub(crate) fn to_dummy_func(&self) -> TypedFunctionDeclaration<'sc> { + TypedFunctionDeclaration { + name: self.name.clone(), + body: TypedCodeBlock { + contents: vec![], + whole_block_span: self.name.span.clone(), + }, + parameters: vec![], + span: self.name.span.clone(), + return_type: self.return_type.clone(), + return_type_span: self.return_type_span.clone(), + visibility: Visibility::Public, + type_parameters: vec![], + } + } +} diff --git a/core_lang/src/semantic_analysis/ast_node/mod.rs b/core_lang/src/semantic_analysis/ast_node/mod.rs index 2fce8b88c02..9057ecd5ea4 100644 --- a/core_lang/src/semantic_analysis/ast_node/mod.rs +++ b/core_lang/src/semantic_analysis/ast_node/mod.rs @@ -171,28 +171,42 @@ impl<'sc> TypedAstNode<'sc> { }) => { let mut methods_buf = Vec::new(); let interface_surface = interface_surface - .into_iter() - .map(|TraitFn { - name, - parameters, - return_type, - return_type_span - }| TypedTraitFn { - name, - return_type_span, - parameters: parameters - .into_iter() - .map(|FunctionParameter { name, r#type, type_span }| - TypedFunctionParameter { - name, - r#type: namespace.resolve_type(&r#type, - &MaybeResolvedType::Partial(PartiallyResolvedType::SelfType)), - type_span } - ).collect(), - return_type: namespace.resolve_type(&return_type, - &MaybeResolvedType::Partial(PartiallyResolvedType::SelfType) - ) - }).collect::>(); + .into_iter() + .map(|TraitFn { + name, + parameters, + return_type, + return_type_span + }| TypedTraitFn { + name, + return_type_span, + parameters: parameters + .into_iter() + .map(|FunctionParameter { name, r#type, type_span }| + TypedFunctionParameter { + name, + r#type: namespace.resolve_type(&r#type, + &MaybeResolvedType::Partial(PartiallyResolvedType::SelfType)), + type_span } + ).collect(), + return_type: namespace.resolve_type(&return_type, + &MaybeResolvedType::Partial(PartiallyResolvedType::SelfType) + ) + }).collect::>(); + let mut l_namespace = namespace.clone(); + // insert placeholder functions representing the interface surface + // to allow methods to use those functions + l_namespace.insert_trait_implementation( + CallPath { + prefixes: vec![], + suffix: name.clone(), + }, + MaybeResolvedType::Partial(PartiallyResolvedType::SelfType), + interface_surface + .iter() + .map(|x| x.to_dummy_func()) + .collect(), + ); for FunctionDeclaration { body, name: fn_name, @@ -204,7 +218,7 @@ impl<'sc> TypedAstNode<'sc> { .. } in methods { - let mut namespace = namespace.clone(); + let mut namespace = l_namespace.clone(); parameters.clone().into_iter().for_each( |FunctionParameter { name, r#type, .. }| { let r#type = namespace.resolve_type( @@ -298,6 +312,7 @@ impl<'sc> TypedAstNode<'sc> { }, ) .collect::>(); + // TODO check code block implicit return let return_type = namespace.resolve_type(&return_type, self_type); let (body, _code_block_implicit_return) = type_check!( diff --git a/forc/src/ops/forc_build.rs b/forc/src/ops/forc_build.rs index c2a7147e00d..d88f8e9ff60 100644 --- a/forc/src/ops/forc_build.rs +++ b/forc/src/ops/forc_build.rs @@ -14,37 +14,6 @@ use core_lang::{ }; use std::{fs, path::PathBuf}; -pub fn print_asm(path: Option) -> Result<(), String> { - // find manifest directory, even if in subdirectory - let this_dir = if let Some(path) = path { - PathBuf::from(path) - } else { - std::env::current_dir().unwrap() - }; - let manifest_dir = find_manifest_dir(&this_dir).ok_or(format!( - "No manifest file found in this directory or any parent directories of it: {:?}", - this_dir - ))?; - let manifest = read_manifest(&manifest_dir)?; - - let mut namespace: Namespace = Default::default(); - if let Some(ref deps) = manifest.dependencies { - for (dependency_name, dependency_details) in deps.iter() { - compile_dependency_lib( - &this_dir, - &dependency_name, - &dependency_details, - &mut namespace, - )?; - } - } - - // now, compile this program with all of its dependencies - let main_file = get_main_file(&manifest, &manifest_dir)?; - - Ok(()) -} - pub fn build(command: BuildCommand) -> Result, String> { let BuildCommand { path, diff --git a/stdlib/src/main.sw b/stdlib/src/main.sw index 91d58f75c03..d1b27bf7861 100644 --- a/stdlib/src/main.sw +++ b/stdlib/src/main.sw @@ -1,25 +1,9 @@ library ops; -pub trait Add { - fn add(self, other: Self) -> Self; -} - -pub trait Subtract { - fn subtract(self, other: Self) -> Self; -} -pub trait Multiply { - fn multiply(self, other: Self) -> Self; -} - -pub trait Divide { - fn divide(self, other: Self) -> Self; -} +// Math ops -impl Subtract for u64 { - fn subtract(self, other: Self) -> Self { - // TODO write asm - 0 - } +pub trait Add { + fn add(self, other: Self) -> Self; } impl Add for u64 { @@ -49,31 +33,241 @@ impl Add for u16 { } } +impl Add for u8 { + fn add(self, other: Self) -> Self { + asm(r1: self, r2: other, r3) { + add r3 r2 r1; + r3: u8 + } + } +} + +pub trait Subtract { + fn subtract(self, other: Self) -> Self; +} + +impl Subtract for u64 { + fn subtract(self, other: Self) -> Self { + asm(r1: self, r2: other, r3) { + sub r3 r1 r2; + r3 + } + } +} + +impl Subtract for u32 { + fn subtract(self, other: Self) -> Self { + asm(r1: self, r2: other, r3) { + sub r3 r1 r2; + r3: u32 + } + } +} + +impl Subtract for u16 { + fn subtract(self, other: Self) -> Self { + asm(r1: self, r2: other, r3) { + sub r3 r1 r2; + r3: u16 + } + } +} + +impl Subtract for u8 { + fn subtract(self, other: Self) -> Self { + asm(r1: self, r2: other, r3) { + sub r3 r1 r2; + r3: u8 + } + } +} + +pub trait Multiply { + fn multiply(self, other: Self) -> Self; +} + +impl Multiply for u64 { + fn multiply(self, other: Self) -> Self { + asm(r1: self, r2: other, r3) { + mul r3 r1 r2; + r3 + } + } +} + +impl Multiply for u32 { + fn multiply(self, other: Self) -> Self { + asm(r1: self, r2: other, r3) { + mul r3 r1 r2; + r3: u32 + } + } +} + +impl Multiply for u16 { + fn multiply(self, other: Self) -> Self { + asm(r1: self, r2: other, r3) { + mul r3 r1 r2; + r3: u16 + } + } +} + +impl Multiply for u8 { + fn multiply(self, other: Self) -> Self { + asm(r1: self, r2: other, r3) { + mul r3 r1 r2; + r3: u8 + } + } +} + +pub trait Divide { + fn divide(self, other: Self) -> Self; +} + +impl Divide for u64 { + fn divide(self, other: Self) -> Self { + asm(r1: self, r2: other, r3) { + div r3 r1 r2; + r3 + } + } +} + +impl Divide for u32 { + fn divide(self, other: Self) -> Self { + asm(r1: self, r2: other, r3) { + div r3 r1 r2; + r3: u32 + } + } +} + +impl Divide for u16 { + fn divide(self, other: Self) -> Self { + asm(r1: self, r2: other, r3) { + div r3 r1 r2; + r3: u16 + } + } +} + +impl Divide for u8 { + fn divide(self, other: Self) -> Self { + asm(r1: self, r2: other, r3) { + div r3 r1 r2; + r3: u8 + } + } +} + + pub trait Eq { fn equals(self, other: Self) -> bool; } -pub trait Cmp { - fn less_than(self, other: Self) -> bool; + +impl Eq for u64 { + fn equals(self, other: Self) -> bool { + asm(r1: self, r2: other, r3) { + eq r3 r1 r2; + r3: bool + } + } +} + +impl Eq for u32 { + fn equals(self, other: Self) -> bool { + asm(r1: self, r2: other, r3) { + eq r3 r1 r2; + r3: bool + } + } +} + +impl Eq for u16 { + fn equals(self, other: Self) -> bool { + asm(r1: self, r2: other, r3) { + eq r3 r1 r2; + r3: bool + } + } +} + +impl Eq for u8 { + fn equals(self, other: Self) -> bool { + asm(r1: self, r2: other, r3) { + eq r3 r1 r2; + r3: bool + } + } +} + + +enum Ordering { + LessOrEqual : (), + Greater : (), +} + +impl Eq for Ordering { + fn equals(self, other: Self) -> bool { + asm(r1: self, r2: other, r3) { + eq r3 r1 r2; + r3: bool + } + } +} + +pub trait Ord { + fn cmp(self, other: Self) -> Ordering; +} { + fn less_or_equal(self, other: Self) -> bool { + let res = self.cmp(other); + res.equals(Ordering::LessOrEqual) + } + fn greater_than(self, other: Self) -> bool { + let res = self.cmp(other); + res.equals(Ordering::Greater) + } +} + +impl Ord for u64 { + fn cmp(self, other: Self) -> Ordering { + let is_greater_than = asm(r1: self, r2: other, r3) { + gt r3 r1 r2; + r3: bool + }; + if is_greater_than { Ordering::Greater } else { Ordering::LessOrEqual } + } } -impl Cmp for u64 { - fn less_than(self, other: Self) -> bool { - // TODO write asm - true +impl Ord for u32 { + fn cmp(self, other: Self) -> Ordering { + let is_greater_than = asm(r1: self, r2: other, r3) { + gt r3 r1 r2; + r3: bool + }; + if is_greater_than { Ordering::Greater } else { Ordering::LessOrEqual } } } -impl Cmp for u32 { - fn less_than(self, other: Self) -> bool { - // TODO write asm - true +impl Ord for u16 { + fn cmp(self, other: Self) -> Ordering { + let is_greater_than = asm(r1: self, r2: other, r3) { + gt r3 r1 r2; + r3: bool + }; + if is_greater_than { Ordering::Greater } else { Ordering::LessOrEqual } } } -impl Cmp for u16 { - fn less_than(self, other: Self) -> bool { - // TODO write asm - true +impl Ord for u8 { + fn cmp(self, other: Self) -> Ordering { + let is_greater_than = asm(r1: self, r2: other, r3) { + gt r3 r1 r2; + r3: bool + }; + if is_greater_than { Ordering::Greater } else { Ordering::LessOrEqual } } }