forked from lcompilers/lpython
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
20 changed files
with
753 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
add_subdirectory(lfortran) | ||
add_subdirectory(runtime) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
set(SRC | ||
parser/tokenizer.cpp | ||
parser/parser.tab.cc | ||
) | ||
add_library(lfortran_lib ${SRC}) | ||
target_include_directories(lfortran_lib BEFORE PUBLIC ${lfortran_SOURCE_DIR}/src) | ||
install(TARGETS lfortran_lib | ||
RUNTIME DESTINATION bin | ||
ARCHIVE DESTINATION lib | ||
LIBRARY DESTINATION lib | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
#ifndef LFORTRAN_ASSERT_H | ||
#define LFORTRAN_ASSERT_H | ||
|
||
// LFORTRAN_ASSERT uses internal functions to perform as assert | ||
// so that there is no effect with NDEBUG | ||
#if defined(WITH_LFORTRAN_ASSERT) | ||
|
||
#if !defined(LFORTRAN_ASSERT) | ||
#define stringize(s) #s | ||
#define XSTR(s) stringize(s) | ||
#define LFORTRAN_ASSERT(cond) \ | ||
{ \ | ||
if (!(cond)) { \ | ||
std::cerr << "LFORTRAN_ASSERT failed: " << __FILE__ \ | ||
<< "\nfunction " << __func__ << "(), line number " \ | ||
<< __LINE__ << " at \n" \ | ||
<< XSTR(cond) << "\n"; \ | ||
abort(); \ | ||
} \ | ||
} | ||
#endif // !defined(LFORTRAN_ASSERT) | ||
|
||
#if !defined(LFORTRAN_ASSERT_MSG) | ||
#define LFORTRAN_ASSERT_MSG(cond, msg) \ | ||
{ \ | ||
if (!(cond)) { \ | ||
std::cerr << "LFORTRAN_ASSERT failed: " << __FILE__ \ | ||
<< "\nfunction " << __func__ << "(), line number " \ | ||
<< __LINE__ << " at \n" \ | ||
<< XSTR(cond) << "\n" \ | ||
<< "ERROR MESSAGE:\n" \ | ||
<< msg << "\n"; \ | ||
abort(); \ | ||
} \ | ||
} | ||
#endif // !defined(LFORTRAN_ASSERT_MSG) | ||
|
||
#else // defined(WITH_LFORTRAN_ASSERT) | ||
|
||
#define LFORTRAN_ASSERT(cond) | ||
#define LFORTRAN_ASSERT_MSG(cond, msg) | ||
|
||
#endif // defined(WITH_LFORTRAN_ASSERT) | ||
|
||
#define LFORTRAN_ERROR(description) \ | ||
std::cerr << description; \ | ||
std::cerr << "\n"; \ | ||
abort(); | ||
|
||
#endif // LFORTRAN_ASSERT_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
#ifndef LFORTRAN_CASTS_H | ||
#define LFORTRAN_CASTS_H | ||
|
||
#include <iostream> | ||
#include <limits> | ||
//#include <lfortran/config.h> | ||
#include <lfortran/assert.h> | ||
|
||
namespace LFortran | ||
{ | ||
|
||
// Reference modifications. | ||
template <typename T> | ||
struct remove_reference { | ||
typedef T type; | ||
}; | ||
template <typename T> | ||
struct remove_reference<T &> { | ||
typedef T type; | ||
}; | ||
|
||
// Use implicit_cast as a safe version of static_cast or const_cast | ||
// for upcasting in the type hierarchy (i.e. casting a pointer to Foo | ||
// to a pointer to SuperclassOfFoo or casting a pointer to Foo to | ||
// a const pointer to Foo). | ||
// When you use implicit_cast, the compiler checks that the cast is safe. | ||
// Such explicit implicit_casts are necessary in surprisingly many | ||
// situations where C++ demands an exact type match instead of an | ||
// argument type convertable to a target type. | ||
// | ||
// The From type can be inferred, so the preferred syntax for using | ||
// implicit_cast is the same as for static_cast etc.: | ||
// | ||
// implicit_cast<ToType>(expr) | ||
|
||
template <typename To, typename From> | ||
inline To implicit_cast(const From &f) | ||
{ | ||
return f; | ||
} | ||
|
||
// When you upcast (that is, cast a pointer from type Foo to type | ||
// SuperclassOfFoo), it's fine to use implicit_cast<>, since upcasts | ||
// always succeed. When you downcast (that is, cast a pointer from | ||
// type Foo to type SubclassOfFoo), static_cast<> isn't safe, because | ||
// how do you know the pointer is really of type SubclassOfFoo? It | ||
// could be a bare Foo, or of type DifferentSubclassOfFoo. Thus, | ||
// when you downcast, you should use this macro. In debug mode, we | ||
// use dynamic_cast<> to double-check the downcast is legal (we die | ||
// if it's not). In normal mode, we do the efficient static_cast<> | ||
// instead. Thus, it's important to test in debug mode to make sure | ||
// the cast is legal! | ||
// This is the only place in the code we should use dynamic_cast<>. | ||
// In particular, you SHOULDN'T be using dynamic_cast<> in order to | ||
// do RTTI (eg code like this: | ||
// if (dynamic_cast<Subclass1>(foo)) HandleASubclass1Object(foo); | ||
// if (dynamic_cast<Subclass2>(foo)) HandleASubclass2Object(foo); | ||
// You should design the code some other way not to need this. | ||
|
||
template <typename To, typename From> // use like this: down_cast<T*>(foo). | ||
inline To down_cast(From *f) // Only accept pointers. | ||
{ | ||
// Ensures that To is a sub-type of From *. This test is here only | ||
// for compile-time type checking, and has no overhead in an | ||
// optimized build at run-time, as it will be optimized away | ||
// completely. | ||
if (false) { | ||
implicit_cast<From *, To>(0); | ||
} | ||
|
||
LFORTRAN_ASSERT(f == NULL || dynamic_cast<To>(f) != NULL); | ||
|
||
return static_cast<To>(f); | ||
} | ||
|
||
template <typename To, typename From> // use like this: down_cast<T&>(foo); | ||
inline To down_cast(From &f) | ||
{ | ||
typedef typename remove_reference<To>::type *ToAsPointer; | ||
// Ensures that To is a sub-type of From *. This test is here only | ||
// for compile-time type checking, and has no overhead in an | ||
// optimized build at run-time, as it will be optimized away | ||
// completely. | ||
if (false) { | ||
implicit_cast<From *, ToAsPointer>(0); | ||
} | ||
|
||
LFORTRAN_ASSERT(dynamic_cast<ToAsPointer>(&f) != NULL); | ||
|
||
return *static_cast<ToAsPointer>(&f); | ||
} | ||
|
||
template <typename To, typename From> | ||
inline To | ||
numeric_cast(From f, | ||
typename std::enable_if<(std::is_signed<From>::value | ||
&& std::is_signed<To>::value) | ||
|| (std::is_unsigned<From>::value | ||
&& std::is_unsigned<To>::value)>::type | ||
* = nullptr) | ||
{ | ||
LFORTRAN_ASSERT(f <= std::numeric_limits<To>::max()); | ||
LFORTRAN_ASSERT(f >= std::numeric_limits<To>::min()); | ||
return static_cast<To>(f); | ||
} | ||
|
||
template <typename To, typename From> | ||
inline To numeric_cast( | ||
From f, | ||
typename std::enable_if<(std::is_signed<From>::value | ||
&& std::is_unsigned<To>::value)>::type * = nullptr) | ||
{ | ||
#ifdef WITH_LFORTRAN_ASSERT | ||
// Above ifdef is needed to avoid a warning about unused typedefs | ||
typedef typename std::make_unsigned<From>::type unsigned_from_type; | ||
LFORTRAN_ASSERT(f >= 0); | ||
LFORTRAN_ASSERT(static_cast<unsigned_from_type>(f) | ||
<= std::numeric_limits<To>::max()); | ||
#endif | ||
return static_cast<To>(f); | ||
} | ||
|
||
template <typename To, typename From> | ||
inline To numeric_cast( | ||
From f, | ||
typename std::enable_if<(std::is_unsigned<From>::value | ||
&& std::is_signed<To>::value)>::type * = nullptr) | ||
{ | ||
#ifdef WITH_LFORTRAN_ASSERT | ||
typedef typename std::make_unsigned<To>::type unsigned_to_type; | ||
LFORTRAN_ASSERT( | ||
f <= static_cast<unsigned_to_type>(std::numeric_limits<To>::max())); | ||
|
||
#endif | ||
return static_cast<To>(f); | ||
} | ||
|
||
} // LFortran | ||
|
||
#endif // LFORTRAN_CASTS_H |
Oops, something went wrong.