Test List
The following table lists all tests included in this documentation.
124 tests have been evaluated with version 0.2.19 of microcad.
Click on the test names to jump to file with the test or click the buttons to get the logs.
Automatic conversion of values when matching arguments
fn f( x: Scalar ) { _ = x; }
f(x=1);
f(x=[1]);
f(x=""); // error
f(""); // error
f(1.0);
f(1);
f([1.0]);
f([1]);
fn g( x: Integer ) { _ = x; }
g(x=1.0); // error
g(x=""); // error
g(""); // error
g(1.0); // error
g([1.0]); // error
g(1);
g([1]);
fn h( x: String ) { _ = x; }
h(x=1.0); // error
h(x="");
h(x=[""]);
h("");
h([""]);
h(1.0); // error
h([1.0]); // error
µcad logo
mod microcad {
use std::geo2d::*;
use std::ops::*;
sketch HalfCircle(radius: Length) {
Circle(radius) - Rect(size = radius * 2).translate(y = radius );
}
sketch IconElement( radius: Length ) {
c = HalfCircle(radius);
r = Rect(width = radius, height = radius * 2);
c.translate(y = radius) | r.translate(x = -radius/2 );
}
pub sketch Icon( radius: Length ) {
prop gap = radius / 5;
IconElement(radius)
.translate(x = -radius-gap, y = 0mm, z = 0mm)
.rotate(z = [0°, -90°, -180°, -270°]);
}
pub sketch Micro( radius: Length, thickness: Length ) {
u = HalfCircle(radius) - HalfCircle(radius-thickness);
r_l = Rect(width = thickness, height = radius * 3);
r_r = Rect(width = thickness, height = radius * 2);
u.translate(y = radius/2)
| r_l.translate(x = -(radius-thickness/2) )
| r_r.translate(x = radius-thickness/2, y=radius/2 );
}
}
use std::ops::*;
radius = 1cm;
thickness = 4mm;
icon = microcad::Icon(radius);
icon;
microcad::Micro(radius, thickness).translate(x=radius*2+icon.gap, y=-radius/2);
Conditions
fn f(x: Integer) {
if x == 5 or x == 4 {
return "match";
} else if x > 0 and x < 4 {
return "no match";
} else {
return "invalid";
}
}
std::print(f(5)); // prints "match"
Ambiguous Look Up for properties/locals and operations
op scale() {}
sketch Sketch(scale: Scalar) { std::geo2d::Rect(size = scale * 40mm) }
Sketch(4.0);
Load an external module within MD test
mod external;
std::debug::assert_valid(external::a);
// file: external.µcad
pub const a =1;
Functions
// function definition
fn f() {}
// call
f();
// parameter
fn f(n: Scalar) {
// result value
n+1
}
use std::debug::*;
assert_eq([ f(1), 2 ]);
assert_eq([ f(4), 5 ]);
fn f(n: Scalar) {
return n+1;
}
use std::debug::*;
assert_eq([ f(1), 2 ]);
assert_eq([ f(4), 5 ]);
fn f(n: Scalar) {
if n > 3 {
n-1
} else {
n+1
}
}
use std::debug::*;
assert_eq([ f(1), 2 ]);
assert_eq([ f(4), 3 ]);
fn f(n: Scalar) {
if n > 3 {
return n-1;
}
n+1
}
use std::debug::*;
assert_eq([ f(1), 2 ]);
assert_eq([ f(4), 3 ]);
fn f(n: Scalar) { // error: not all paths return a value
if n > 3 {
n-1
}
}
use std::debug::*;
assert_eq([ f(1), 2 ]);
assert_eq([ f(4), 3 ]);
Modules
mod a {
pub mod b {
pub mod c {
pub part M1() {}
}
}
pub part M2() {}
}
a::b::c::M1();
a::M2();
Scope tests
Scopes
a = 1;
__builtin::debug::assert_valid(a);
__builtin::debug::assert_invalid(b);
__builtin::debug::assert_invalid(c);
{
__builtin::debug::assert_valid(a);
__builtin::debug::assert_invalid(b);
__builtin::debug::assert_invalid(c);
b = 2;
__builtin::debug::assert_valid(a);
__builtin::debug::assert_valid(b);
__builtin::debug::assert_invalid(c);
c = 3;
__builtin::debug::assert_valid(a);
__builtin::debug::assert_valid(b);
__builtin::debug::assert_valid(c);
};
__builtin::debug::assert_valid(a);
__builtin::debug::assert_invalid(b);
__builtin::debug::assert_invalid(c);
Usage of semicolon with Workbenches
use std::geo2d::Circle;
use std::ops::translate;
{ // op with body
Circle(radius = 5mm);
}.translate(y=[-34mm/2 , 34mm/2]);
use std::geo2d::Circle;
use std::ops::translate;
// op without body
Circle( radius = 5mm )
.translate(y = [-34mm/2 , 34mm/2]);
use std::geo2d::Circle;
use std::ops::translate;
{
Circle(radius = 5mm) // missing semicolon is ok.
}.translate(y=[-34mm/2 , 34mm/2]);
{}.std::ops::translate(x = 5mm) // warning: Calling operation on empty geometry
use std::geo2d::Circle;
Circle(radius = 2mm) { Circle(radius = 1mm); } // parse_error: sketch with body
std::ops::translate(x = 3.0mm); // error: Cannot call operation without workpiece.
{}.std::ops::translate(x = 3.0mm); // warning: Calling operation on empty geometry
use std::geo2d::Circle;
use std::ops::translate;
// group
{
Circle(radius = 1mm);
Circle(radius = 2mm);
}
use std::geo2d::Circle;
use std::ops::translate;
// assignment + group
a = {
Circle(radius = 1mm);
Circle(radius = 2mm);
};
Statement Usage
The following table shows which elements (rows) may occur in which Context (columns):
| Context/Element | Source File | Module | Pre-Init | Init | Work-bench | Body | Func-tion |
|---|---|---|---|---|---|---|---|
sketch, part, op | yes | yes | - | - | - | - | - |
mod | yes | yes | - | - | - | - | - |
fn | yes | yes | - | - | - | - | - |
init | - | - | yes | - | yes | - | - |
use | yes | yes | yes | yes | yes | yes | yes |
pub use | yes | yes | - | - | - | - | - |
return | - | - | - | - | - | - | yes |
if | yes | - | - | - | yes | yes | yes |
@input | - | - | - | - | yes | ?yes? | - |
x = 1 | yes | yes | - | yes | yes | yes | yes |
const | yes | yes | - | - | - | - | - |
prop | - | - | - | - | yes | - | - |
| expression | yes | - | - | - | yes | yes | yes |
| Test | Test | Test | Test | Test | Test | Test |
Source
sketch F() {} F();
mod m {}
fn f() {} f();
init() {} // error
use std;
pub use std;
return 1; // error
if std::math::PI == 3 { __builtin::geo2d::Circle(radius=1mm); }
const B = 1;
a = 1;
prop a = 1; // error
1 + 2;
__builtin::geo2d::Circle(radius=1mm);
Module
mod k {
sketch F() {}
}
mod k {
mod m {}
}
mod k {
fn f() {}
}
mod k {
init() { } // error
}
mod k {
use std::geo2d;
}
mod k {
pub use std::geo2d;
}
mod k {
return 1; // error
}
mod k {
if std::math::PI == 3 { __builtin::geo2d::Circle(radius=1); } // error
}
mod k {
const B = 1;
}
mod k {
a = 1; // error
}
mod k {
prop a = 1; // error
}
mod k { // warning
1 + 2; // error
}
mod k { // warning
__builtin::geo2d::Circle(radius=1mm); // error
}
Pre-Init
sketch K() {
sketch F() {} K(); // error
init(l:Length) {} } K();
sketch K() {
mod m {} // error
init(l:Length) {} } K();
sketch K() {
fn f() {} f(); // error
init(l:Length) {} } K();
sketch K() {
init() {}
init(l:Length) {} } K();
sketch K() {
use std;
init(l:Length) {} } K();
sketch K() {
pub use std; // error
init(l:Length) {} } K();
sketch K() {
return 1; // error
init(l:Length) {} } K();
sketch K() {
if std::math::PI == 3 { } // error
init(l:Length) {} } K();
sketch K() {
const B = 1;
init(l:Length) {} } K();
sketch K() {
a = 1; // error
init(l:Length) {} } K();
sketch K() {
prop a = 1; // error
init(l:Length) {} } K();
sketch K() {
1 + 2; // error
init(l:Length) {} } K();
sketch K() {
__builtin::geo2d::Circle(radius=1mm); // error
init(l:Length) {} }
Init
sketch K() { init(l:Length) { // warning
sketch F() {} // error
} } K(1cm);
sketch K() { init(l:Length) { // warning
mod m {} // error
} } K(1cm);
sketch K() { init(l:Length) { // warning
fn f() {} // error
} } K(1cm);
sketch K() { init(l:Length) { // warning
init() {} // error
} } K(1cm);
sketch K() { init(l:Length) {
use std;
} } K(1cm);
sketch K() { init(l:Length) { // warning
pub use std; // error
} } K(1cm);
sketch K() { init(l:Length) {
return l; // error
} } K(1cm);
sketch K() { init(l:Length) {
if std::math::PI == l { } // error
} } K(1cm);
sketch K() { init(l:Length) {
const B = l; // error
} } K(1cm);
sketch K() { init(l:Length) {
a = l;
} } K(1cm);
sketch K() { init(l:Length) {
prop a = l; // error
} } K(1cm);
sketch K() { init(l:Length) {
l + 2; // error
} } K(1cm);
sketch K() { init(l:Length) {
__builtin::geo2d::Circle(radius=l); // error
} } K(1cm);
Workbench
sketch K() {
sketch F() {} F(); // error
} K();
sketch K() {
mod m {} // error
} K();
sketch K() {
fn f() {} f();
} K();
sketch K() {
init() {}
} K();
sketch K() {
use std;
} K();
sketch K() {
pub use std; // error
} K();
sketch K() {
return 1; // error
} K();
sketch K() {
if std::math::PI == 3 { }
} K();
sketch K() {
@input
} K();
sketch K() {
const B = 1;
} K();
sketch K() {
a = 1;
} K();
sketch K() {
prop a = 1;
} K();
sketch K() {
1 + 2;
} K();
sketch K() {
__builtin::geo2d::Circle(radius=1mm);
} K();
Body
{
sketch F() {} // error
}
{
mod m {} // error
}
{
fn f() {} f(); // error
}
{
init() {} // error
}
{
use std;
}
{
pub use std; // error
}
{
return 1; // error
}
{
if std::math::PI == 3 { }
}
{
@input
}
{
const B = 1; // error
}
{
a = 1;
}
{
prop a = 1; // error
}
{
1 + 2;
}
{
__builtin::geo2d::Circle(radius=1mm);
}
Function
fn f() {
sketch S() {} // error
} f();
fn f() {
mod m {} // error
} f();
fn f() {
fn f() {} // error
} f();
fn f() {
init() {} // error
} f();
fn f() {
use std;
} f();
fn f() {
pub use std; // error
} f();
fn f() {
return 1;
} f();
fn f() {
if std::math::PI == 3 { __builtin::geo2d::Circle(radius=1); }
} f();
fn f() {
const B = 1; // error
} f();
fn f() {
a = 1;
} f();
fn f() {
prop a = 1; // error
} f();
fn f() {
1 + 2;
} f();
fn f() {
__builtin::geo2d::Circle(radius=1mm);
} f();
Use statement tests
// use debug from `std/module.µcad`
use std::debug::assert;
assert(true);
// use all symbols from std::debug for test checks
use std::debug::*;
// use symbol `circle` in file `geo2d.µcad`
use std::geo2d::Circle;
assert_valid(Circle);
// use all symbols in file `geo3d.µcad`
use std::geo3d::*;
assert_valid(Sphere);
assert_valid(Cube);
// alias `Circle` in `std/geo2d/mod.µcad` into `foo`
use std::geo2d::Circle as foo;
assert_valid(foo);
// use print from `std/module.µcad`
use std::print;
assert_valid(print);
print("Hello");
// public use operation from `std/module.µcad`
pub use std::ops;
assert_valid(ops);
assert_valid(use_test::ops);
part MyPart() {
Circle(radius=1);
Sphere(radius=1);
}
assert_valid(MyPart);
use std::geo2d::*;
use Rect as Cap;
Cap(width=1mm,height=1mm);
// use symbol `circle` in file `geo2d.µcad`
use std::geo2d::Circle;
// use all symbols in file `geo3d.µcad`
use std::geo3d::*;
// alias `bar` in `std/text/foo.µcad` into `baz`
use std::math::abs as baz;
// use print from `std/module.µcad`
use std::print;
// public use operation from `std/module.µcad`
pub use std::ops;
// use debug from `std/module.µcad`
use std::debug;
debug::assert(true);
part my_part3d() { Sphere(radius=1mm); }
part my_part2d() { Circle(radius=1mm); }
x = my_part2d();
y = my_part3d();
z = baz(-1.0);
fn f() {
use std::math::abs;
x = abs(-1.0);
return x;
}
f();
fn f() {
use std::math::*;
x = abs(-1.0);
return x;
}
f();
mod my {
mod name {
pub mod space {
pub use std::geo2d::*;
}
}
pub use name::space::*;
}
my::Circle(r = 4mm);
my::Rect(size = 40mm);
Value Declarations
| Keyword(s) | Context | Description | Example |
|---|---|---|---|
| - | source, workbench, function | local value | a=1 |
| - | init | property (if in building plan), else local value | a=1 |
prop | workbench | model property | prop a=1 |
const | module | private module value | const a=1; |
pub, (pub const) | module | public module value | pub a=1;, pub const a=1; |
use | module, source, workbench, function, init | private usage | use std::geo3d; |
pub use | module, source | public usage | pub use std::geo3d; |
fn | module, source, workbench | private function | fn() {} |
pub fn | module, source | public function | pub fn() {} |
use std::debug::*;
mod module {
use std::debug::*;
// private module variable
const value = 1;
// public module variable
pub pub_value = 2;
pub mod pub_sub_module {
// pre-init code
use std::debug::*;
// private module variable
const value = 3;
// public module variable
pub pub_value = 4;
// private workbench
sketch PrivateWorkbench() {}
// public workbench
pub sketch Workbench(param = 5) {
const sketch_local = 6;
init(alt_param = 7) {
init_local = 8;
assert_eq([super::value, 1]);
assert_eq([super::pub_value, 2]);
assert_eq([value, 3]);
assert_eq([pub_value, 4]);
assert_invalid(param);
assert_eq([sketch_local, 6]);
assert_eq([alt_param, 7]);
assert_eq([init_local, 8]);
prop param = 5; // needed to compile
}
// property of sketch
prop property = 9;
// post init code
assert_eq([super::value,1]);
assert_eq([super::pub_value, 2]);
assert_eq([value, 3]);
assert_eq([pub_value, 4]);
assert_eq([param, 5]);
assert_eq([sketch_local, 6]);
assert_invalid(alt_param);
assert_invalid(init_local);
assert_eq([property, 9]);
function();
}
fn function(fn_param = 10) {
assert_eq([super::value, 1]);
assert_eq([super::pub_value, 2]);
assert_eq([value, 3]);
assert_eq([pub_value, 4]);
assert_invalid(param);
// assert_invalid(Workbench);
assert_eq([fn_param, 10]);
return 0;
}
}
pub fn function(fn_param = 11) {
assert_eq([value, 1]);
assert_eq([pub_value, 2]);
assert_invalid(pub_sub_module::value);
assert_eq([pub_sub_module::pub_value, 4]);
assert_invalid(Workbench);
assert_invalid(PrivateWorkbench);
assert_eq([fn_param, 11]);
return 0;
}
}
// source file code
assert_invalid(module::value);
assert_eq([module::pub_value, 2]);
assert_invalid(module::pub_sub_module::value);
assert_eq([module::pub_sub_module::pub_value, 4]);
assert_eq([module::pub_sub_module::Workbench().property, 9]);
assert_invalid(module::pub_sub_module::PrivateWorkbench);
assert_eq([module::function(), 0]);
Visibility
mod my {
mod mod_private {
pub const_public = 1;
const const_private = 1;
}
pub mod mod_public {
pub const_public = 1;
const const_private = 1;
}
}
__builtin::debug::assert_valid(my::mod_public::const_public);
__builtin::debug::assert_invalid(my::mod_public::const_private);
__builtin::debug::assert_invalid(my::mod_private::const_public);
__builtin::debug::assert_invalid(my::mod_private::const_private);