rustpp: Try to fix for loop semantics
This commit is contained in:
@@ -27,14 +27,16 @@
|
|||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
#define rustpp_for(value, iter) \
|
#define rustpp_for(value, iter) \
|
||||||
auto RUSTPP_UNIQ (iterator) = iter.into_iter (); \
|
if (auto RUSTPP_UNIQ (iterator) = iter.into_iter (); auto RUSTPP_UNIQ (opt) = RUSTPP_UNIQ (iterator).next ()) \
|
||||||
for (auto value = RUSTPP_UNIQ (iterator).next (); value.is_some (); value = RUSTPP_UNIQ (iterator).next ())
|
for (auto value = RUSTPP_UNIQ (opt).unwrap_unchecked (); \
|
||||||
|
RUSTPP_UNIQ (opt).is_some (); \
|
||||||
|
RUSTPP_UNIQ (opt) = RUSTPP_UNIQ (iterator).next (), value = RUSTPP_UNIQ (opt).unwrap_unchecked ())
|
||||||
|
|
||||||
|
|
||||||
#ifndef I_AM_RUSTPP_RUNTIME
|
#ifndef I_AM_RUSTPP_RUNTIME
|
||||||
|
|
||||||
#define main rustpp__main
|
#define main rustpp__main
|
||||||
#define new __rustpp__new
|
#define new rustpp__new
|
||||||
|
|
||||||
#ifndef NO_RUSTPP_FOR
|
#ifndef NO_RUSTPP_FOR
|
||||||
#define for(...) rustpp_for (__VA_ARGS__)
|
#define for(...) rustpp_for (__VA_ARGS__)
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
//! Rusty primitive types
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|||||||
+59
-30
@@ -1,12 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
// all C/++ headers must be imported first
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <print> // IWYU pragma: export
|
|
||||||
|
|
||||||
#include "panic.hh" // IWYU pragma: export
|
#include "panic.hh" // IWYU pragma: export
|
||||||
#include "primitives.hh" // IWYU pragma: export
|
#include "primitives.hh" // IWYU pragma: export
|
||||||
|
|
||||||
// no reorder
|
// keywords.hh must come last; changes language semantics with macros
|
||||||
#include "keywords.hh" // IWYU pragma: export
|
#include "keywords.hh" // IWYU pragma: export
|
||||||
|
|
||||||
type Cstr = char *;
|
type Cstr = char *;
|
||||||
@@ -37,37 +37,41 @@ mod option {
|
|||||||
public:
|
public:
|
||||||
makeSelf (Option<T>);
|
makeSelf (Option<T>);
|
||||||
|
|
||||||
pub static fn Some (T value) -> Self {
|
static fn Some (T value) -> Self {
|
||||||
Self op;
|
Self op;
|
||||||
op.value.Some = value;
|
op.value.Some = value;
|
||||||
op.variant = variant::Some;
|
op.variant = variant::Some;
|
||||||
return op;
|
return op;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub static fn None (T *_type = (T *) (0)) -> Self {
|
static fn None (T *_type = (T *) (0)) -> Self {
|
||||||
Self op;
|
Self op;
|
||||||
op.value.None = 0;
|
op.value.None = 0;
|
||||||
op.variant = variant::None;
|
op.variant = variant::None;
|
||||||
return op;
|
return op;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn return_value () -> int {
|
fn return_value () -> int {
|
||||||
return self.is_some ();
|
return self.is_some ();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_some () -> bool {
|
fn is_some () -> bool {
|
||||||
return variant == variant::Some;
|
return variant == variant::Some;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_none () -> bool {
|
fn is_none () -> bool {
|
||||||
return variant == variant::None;
|
return variant == variant::None;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub operator bool () {
|
operator bool () {
|
||||||
return this->is_some ();
|
return this->is_some ();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unwrap () -> T {
|
fn unwrap_unchecked () -> T {
|
||||||
|
return value.Some;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unwrap () -> T {
|
||||||
match (variant) {
|
match (variant) {
|
||||||
arm (variant::Some, return value.Some);
|
arm (variant::Some, return value.Some);
|
||||||
arm (variant::None, panic ("Called Option::unwrap() on a None value"));
|
arm (variant::None, panic ("Called Option::unwrap() on a None value"));
|
||||||
@@ -75,7 +79,7 @@ mod option {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename U>
|
template <typename U>
|
||||||
pub fn map (U (f) (T)) -> Option<U> {
|
fn map (U (f) (T)) -> Option<U> {
|
||||||
match (variant) {
|
match (variant) {
|
||||||
arm (variant::Some, return Some (f (value.Some)));
|
arm (variant::Some, return Some (f (value.Some)));
|
||||||
arm (variant::None, return None<U> ());
|
arm (variant::None, return None<U> ());
|
||||||
@@ -115,42 +119,68 @@ mod result {
|
|||||||
|
|
||||||
// TODO: destructor for Result
|
// TODO: destructor for Result
|
||||||
|
|
||||||
pub static fn Ok (T value) -> Self {
|
static fn Ok (T value) -> Self {
|
||||||
Self result;
|
Self result;
|
||||||
result.value.Ok = value;
|
result.value.Ok = value;
|
||||||
result.variant = variant::Ok;
|
result.variant = variant::Ok;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub static fn Err (E error) -> Self {
|
static fn Err (E error) -> Self {
|
||||||
Self result;
|
Self result;
|
||||||
result.value.Err = error;
|
result.value.Err = error;
|
||||||
result.variant = variant::Err;
|
result.variant = variant::Err;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_ok () -> bool {
|
fn is_ok () -> bool {
|
||||||
return variant == variant::Ok;
|
return variant == variant::Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_err () -> bool {
|
fn is_err () -> bool {
|
||||||
return variant == variant::Err;
|
return variant == variant::Err;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unwrap () -> T {
|
fn ok () -> option::Option<T> {
|
||||||
|
match (variant) {
|
||||||
|
arm (variant::Ok, return option::Some (value.Ok));
|
||||||
|
arm (variant::Err, return option::None<T> ());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn err () -> option::Option<E> {
|
||||||
|
match (variant) {
|
||||||
|
arm (variant::Err, return option::Some (value.Err));
|
||||||
|
arm (variant::Ok, return option::None<T> ());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unwrap () -> T {
|
||||||
match (variant) {
|
match (variant) {
|
||||||
arm (variant::Ok, return value.Ok);
|
arm (variant::Ok, return value.Ok);
|
||||||
arm (variant::Err, panic ("Called Result::unwrap() on Err value"));
|
arm (variant::Err, panic ("Called Result::unwrap() on Err value"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unwrap_err () -> E {
|
fn unwrap_err () -> E {
|
||||||
match (variant) {
|
match (variant) {
|
||||||
arm (variant::Ok, panic ("Called Result::unwrap_err() on Ok value"));
|
arm (variant::Ok, panic ("Called Result::unwrap_err() on Ok value"));
|
||||||
arm (variant::Err, return value.Err);
|
arm (variant::Err, return value.Err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Constructs a Result with variant Err and value `Err(value)`
|
||||||
|
template <typename T, typename E>
|
||||||
|
fn Err (E error) -> Result<T, E> {
|
||||||
|
return Result<T, E>::Err (error);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Constructs a Result with variant Ok and value `Ok(value)`
|
||||||
|
template <typename T, typename E>
|
||||||
|
fn Ok (T value) -> Result<T, E> {
|
||||||
|
return Result<T, E>::Ok (value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mod ptr {
|
mod ptr {
|
||||||
@@ -159,12 +189,11 @@ mod ptr {
|
|||||||
T *value;
|
T *value;
|
||||||
makeSelf (Nonnull<T>);
|
makeSelf (Nonnull<T>);
|
||||||
|
|
||||||
pub static fn __rustpp__new (T *value) -> option::Option<Self> {
|
static fn rustpp__new (T *value) -> option::Option<Self> {
|
||||||
switch (value) {
|
if (value) {
|
||||||
case nullptr:
|
return option::Some ((Self) { value });
|
||||||
return option::Some ({ value });
|
} else {
|
||||||
default:
|
return option::None<Self> ();
|
||||||
return option::None (&value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,7 +229,7 @@ mod iter {
|
|||||||
|
|
||||||
mod slice {
|
mod slice {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class Iter: public iter::Iterator<T *> {
|
class Iter: public iter::Iterator<ptr::Nonnull<T>> {
|
||||||
T *head;
|
T *head;
|
||||||
T *tail;
|
T *tail;
|
||||||
|
|
||||||
@@ -209,15 +238,15 @@ mod slice {
|
|||||||
public:
|
public:
|
||||||
makeSelf (Iter<T>);
|
makeSelf (Iter<T>);
|
||||||
|
|
||||||
static fn __rustpp__new (T *head, usize len) -> Self {
|
static fn rustpp__new (T *head, usize len) -> Self {
|
||||||
return { head, head + len };
|
return { head, head + len };
|
||||||
}
|
}
|
||||||
|
|
||||||
fn next () -> option::Option<T *> override {
|
fn next () -> option::Option<ptr::Nonnull<T>> override {
|
||||||
if (head < tail)
|
if (head < tail)
|
||||||
return option::Some (head++);
|
return ptr::Nonnull<T>::rustpp__new (head++);
|
||||||
else
|
else
|
||||||
return option::None<T *> ();
|
return option::None<ptr::Nonnull<T>> ();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn into_iter () -> Self & {
|
fn into_iter () -> Self & {
|
||||||
@@ -232,7 +261,7 @@ mod slice {
|
|||||||
|
|
||||||
makeSelf (Slice<T>);
|
makeSelf (Slice<T>);
|
||||||
fn into_iter () -> Iter<T> {
|
fn into_iter () -> Iter<T> {
|
||||||
return Iter<T>::__rustpp__new (self.ptr, self.len);
|
return Iter<T>::rustpp__new (self.ptr, self.len);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -276,7 +305,7 @@ mod vec {
|
|||||||
|
|
||||||
makeSelf (Vec<T>);
|
makeSelf (Vec<T>);
|
||||||
|
|
||||||
static fn __rustpp__new () -> Self {
|
static fn rustpp__new () -> Self {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -347,4 +376,4 @@ mod prelude {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
using mod prelude;
|
use mod prelude;
|
||||||
|
|||||||
+7
-7
@@ -1,5 +1,6 @@
|
|||||||
#include <print>
|
#include <print>
|
||||||
|
|
||||||
|
// rust.hh changes language semantics, so must be included last!
|
||||||
#include "rust.hh"
|
#include "rust.hh"
|
||||||
|
|
||||||
fn main () -> i32 {
|
fn main () -> i32 {
|
||||||
@@ -9,16 +10,15 @@ fn main () -> i32 {
|
|||||||
v.push (20);
|
v.push (20);
|
||||||
v.push (30);
|
v.push (30);
|
||||||
|
|
||||||
std::println("Printing contents of v");
|
std::println ("Printing contents of v by reference");
|
||||||
for (x, v) {
|
for (x, v.iter ()) {
|
||||||
std::println ("{}", x.unwrap ());
|
std::println ("{}", *x);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is okay, because the previous for loop moved out of v
|
// This is okay, because the previous for loop borrowed v
|
||||||
// leaving it default-initialized.
|
std::println ("Printing contents of v by value");
|
||||||
std::println("Printing contents of v");
|
|
||||||
for (x, v) {
|
for (x, v) {
|
||||||
std::println ("{}", x.unwrap ());
|
std::println ("{}", x);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user