Pretty C는 C와 호환되는 새로운 스크립팅 언어입니다. Pretty C는 동적 타이핑, 일반 반복, 리소스 추적 및 기타 기능을 통해 프로그램을 향상시킵니다. 그리고 C 및 모든 해당 라이브러리와 역호환됩니다! Lua, Python, JavaScript 및 Lisp에서 영감을 얻었습니다. Pretty C를 사용하여 head
유틸리티를 순진하게 다시 구현하는 방법은 다음과 같습니다.
#include "pretty.h"
int main ( int argc , string argv [])
{
if ( argc above 1 )
with ( f , fclose , fopen ( argv [ 1 ], "r" ))
fortimes ( line , 10 )
with ( buf , free , vector ( 200 , char , 0 ))
when ( fgets ( buf , 200 , f ))
then print ( buf )
otherwise 0 ;
else
println ( "Please provide an input file" );
return EXIT_SUCCESS ;
}
Pretty C의 목표는 다음과 같습니다.
#include
가 가능한 헤더 전용 라이브러리입니다!) 모든 코드베이스를 초보자에게 친숙한 코드베이스로 바꿔줍니다.저장소 체크아웃
git clone https://github.com/aartaka/pretty.c
아니면 간단히 pretty.h
파일을 복사하세요. Pretty C는 헤더 전용 라이브러리이므로 다음을 수행할 수 있습니다.
#include "pretty.h"
pretty.h
드롭한 디렉토리의 모든 파일에서. 또는 Pretty C에 대한 경로를 포함( -I
) 경로로 지정하는 경우 실제로 모든 파일에서 가능합니다.
C를 다시 힙하게 만드는 모든 예쁜 변화는 다음과 같습니다.
true
, false
및 bool
.uint64_t
와 같은 고정 너비 정수 유형의 경우 stdint.h.and
for &&
및 or
for ||
포함하여 일반 연산자에 대한 읽기 가능한 대안을 제공합니다. . 정돈된! 모두가 이것을 정의하는데 왜 제공하지 않습니까?
max
과 min
.len
.default
.limit
.between
.divisible
숫자가 다른 숫자로 모듈로 나누어 떨어지는지 확인합니다. 유형 별칭:
string
== char*
.byte
== char
.bytes
== char*
.any
== void*
.uchar
.ushort
.uint
.ulong
. 주로 Lua와 Lisp를 모델로 삼았습니다.
eq
, iso646.h
not_eq
만 있기 때문입니다.is
==
도 의미합니다.iso646.h
에서 일관되지 않게 호출되었던 작업(각각 compl
및 xor
)에 대한 bitnot
및 bitxor
.success
및 fail
/ failure
success == 0
.below
, above
, upto
및 downto
비교 연산자입니다.even
, odd
, positive
, negative
, zero
및 empty
.NULL
의 경우 nil
.until
while
.else if
에 대한 elif
.if(!...)
및 elifnt
에 대한 ifnt
(예상하셨을 겁니다.)do
의 별칭으로 Lua에서 repeat
.done~/~finish
및 pass
각각 break
및 continue
에 대한 별칭입니다.always
, forever
, loop
및 indefinitely
사용하여 무한(이벤트? 서버?) 루프를 만들 수 있습니다. always println ( "After all this time?" );
comment
으로 처리하는 동시에 컴파일러가 분석/최적화할 수 있도록 never
합니다(Clojure comment
형식과 유사). never println ( "This never runs, but never gets outdated, because compiler will shout at you if it does." );
네, 할 수 있어요
var t = time ( 0 );
let lt = localtime ( & t );
local at = asctime ( lt );
println ( at );
프리티C와 함께
print는 당신이 먹이는 모든 것을 print
. println
그 뒤에 개행 문자를 추가합니다.
println ( 3.1 );
print ( "Hello world!n" );
모든 것을 비교해 보세요!
equal ( "NA" , line ); // true
equal ( 0.3 , 0.2 + 0.1 ); // true
삼항은 무섭기 때문에 일반 텍스트를 추가해도 문제가 되지 않습니다. if
와 else
사용되지만 Python/Lisp와 매우 유사해 보이는 적절한 언어적 대안이 있습니다.
return when some_condition
then do_something ()
other do_something_else ();
아래에는 삼항이 있습니다.
when
가독성을 위해서만 제공됩니다.when
의 음수 버전이 not
것으로 확장되지 unless
.then
?
.other
/ otherwise
:
로 확장됩니다. otherwise
절이 불필요한 경우 only
사용할 수 있는 경우도 있습니다.
return when done ()
then 42 only ;
그리고 다음 조건에 대해서는 otherwhen
return when c is 'A'
then 'a'
otherwhen c is 'B'
then 'b' only ;
for
이러한 매크로는 특정 for
루프 패턴에 대한 별칭이며, 각각 자주 사용되는 for
루프 사용 중 일부를 추상화합니다.
foreach (var, type, length, ...)
이는 vararg 표현식으로 초기화된 배열 또는 메모리 영역을 탐색합니다. 반복될 때마다 var
해당 배열 요소에 대한 포인터로 설정됩니다. 예, 포인터입니다. 필요한 경우 해당 요소를 수정할 수 있습니다.
foreach ( i , int , 10 , vector ( 10 , int , 1 , 2 , 3 , 3 , 4 , 5 ))
println ( * i );
또한 vector
의 사용을 보여줍니다.
forthese (var, type, ...)
제공된 varargs를 반복하여 이들 각각을 -d var
type
에 바인딩합니다. 위의 루프는 다음과 같이 번역될 수 있습니다.
forthese ( i , int , 1 , 2 , 3 , 3 , 4 , 5 )
println ( i );
fortimes (var, times)
0에서 양수로 바뀌는 경우가 자주 발생합니다. 당신의 시간을 꽤 절약해 줍니다.
for ( int i = 0 ; i < 28 ; i ++ )
println ( i + 1 );
그것을 간단하게 바꾸면
fortimes ( i , 28 )
println ( i + 1 );
println ( "28 stab wounds, you didn't want to leave him a chance, huh?" );
forrange (var, init, target)
init
에서 target
까지 숫자 범위를 반복합니다. Pythonesque. forrange
사용한 섭씨에서 화씨로의 변환 루프는 다음과 같습니다.
forrange ( c , -10 , 20 )
printf ( "Celsius %i = Fahrenheit %fn" , c , ( 32 + ( c * 1.8 )));
init
및 target
부호 있는 정수와 부호 없는 임의의 정수입니다. 그리고 init
target
보다 클 수 있으며, 이 경우 반복 단계에서 변수가 감소합니다.
forrangeby (var, type, init, target, by)
매번 단계별 by
iter
에서 target
까지 type
-d var
반복합니다. Pythonesque.
forrangeby ( x , double , 1.0 , 10.0 , 0.5 )
println ( x );
이를 통해 일반적인 패턴에 대한 빠르고 정확한 할당이 가능합니다. 대부분 C++를 모델로 했습니다.
new (type, ...)
C++ new
연산자는 훌륭하므로 C에서 비슷한 것을 사용해도 문제가 되지 않을 것입니다. 그렇죠? 더 이상 묻지 마세요:
struct ListNode {
int val ;
struct ListNode * next ;
};
struct ListNode * node = new ( struct ListNode , 2 , new ( struct ListNode , 1 , nil ));
또는 원하는 경우 위에 더 많은 구문을 추가할 수 있습니다.
#define cons ( val , ...) new(struct ListNode, val, __VA_ARGS__)
cons ( 2 , cons ( 1 , nil ));
vector (length, type, ...)
다시 C++. std::vector
추론하기 쉬운 매우 유용하고 다재다능한 데이터 구조입니다. 이 매크로는 C++만큼 기능적이지는 않지만 "이러한 내용으로 많은 요소의 배열을 할당"하는 빈번한 패턴을 단순화합니다.
double * vec = vector ( 10 , double , 1 , 2 , 3 , 4 , 5 );
delete (...)
리소스를 free
사용하는 것을 좋아하지 않고 더 멋진 C++ 이름을 선호하는 경우.
그렇지 않으면 free
와 동일합니다.
이는 새로운 로컬 바인딩을 설정하고, 지연된 계산을 보장하거나, 그 이후의 블록에서 작동합니다.
lambda (ret, name, ...)
(GCC, Clang 또는 C++)중첩된 함수/람다/클로저, 이제 C로!
int * arr = vector ( 10 , int , 23423 , 23423 , 234 , 5233 , 6 , 4 , 34 , 643 , 3 , 9 );
lambda ( int , cmp , int * a , int * b ) {
return * a - * b ;
};
qsort ( arr , 10 , sizeof ( int ), cmp );
// arr becomes {3, 4, 6, 9, 34, 234, 643, 5233, 23423, 23423}
with (var, close, ...)
이렇게 하면 해제 절차( close
)를 미리 제공하므로 해제 후 사용이 발생하지 않습니다. 동적으로 할당된 개체 및 파일 지정자에 특히 유용합니다.
with ( file , fclose , fopen ( "hello.txt" , "w" ))
fprintf ( file , "Hello world!n" );
단점 중 하나는 바인딩된 var
가 void *
이므로 사용하기 전에 해당 유형으로 강제 변환해야 할 수도 있다는 것입니다.
defer (...)
다음 블록 이후에 실행될 코드를 오프로드합니다. Go에서처럼 기능이 끝나면 안 됩니다. 불가능한 C에서는 구현하기가 어렵습니다. 그래도 Pretty C defer
는 충분히 유용합니다.
try
하고 catch
멋진 오류 처리 기능이 이제 C로 제공됩니다. errno 참조에서 리팩터링된 예:
try log ( 0.0 );
catch ( NOERR )
println ( "No error." );
catch ( EDOM , ERANGE )
println ( "Math error!" );
NOERR
및 NOERROR
도 오류 전환의 편의를 위해 Pretty C에서 제공됩니다.
make indent
실행하면 대부분의 스타일 세부 사항이 처리됩니다.