사용자:KORsnack/E Script

위키백과, 우리 모두의 백과사전.

예약어[편집]

다음의 단어들은 예약어로서 변수, 함수, 클래스의 이름에 사용할 수 없다.

Array, as, bool, Cfunc, char, class, closed, DestroyClass, do, double, else, endif, escape, file, float, for, function, gofirst, goto, if, int, long, main, new, opened, PointerOf, redef, repeat, signed, static, string, switch, VARLIST, VARLIST_MAX, void,
while

기본 구문[편집]

전처리문[편집]

전처리문의 경우에는 %와 함께 시작되며 사용되는 예약어는 with, define ~ as ~, if, ifdef, ifndef, defined 가 있다.

%with = eh파일을 포함시킴.

 %with Header1.eh
 %with Header2.txt
 %with Folder1/Header3	// 확장자 없이도 된다

%define = 특정 단어를 또 다른 구문, 단어등으로 바꿔줌

 %define __E_Language_Header_stio_eh__	// 실제 헤더에 사용
 %define Hello as say("Hello, World?%n%");

%if = 조건이 맞을경우 endif까지 실행

%ifdef = 특정 단어가 선언되었을 경우 endif까지 실행

%ifndef = 특정 단어가 선언되지 않았을 경우 endif까지 실행

%defined = 특정 단어가 선언되었을 경우 참

 %if !(%defined __E_Language_Header_stio_eh__)
 // %ifndef __E_Language_Header_stio_eh__  와 같음
 %define __E_Language_Header_stio_eh__
 // 헤더 내용
 %endif

main함수[편집]

모든 E언어 프로그램은 main함수가 하나씩 있어야 한다. 2개 이상이 있거나 하나도 없을 경우에는 에러를 반환한다.

main함수는 인수를 없이 쓰거나 두개의 매개변수를 사용한다.

main() {}
// 혹은
main(uint argn, string Array[] args) {}

두개의 인수가 사용된 경우 실행파일 뒤에 사용할 옵션따위를 쓸수 있다.

C:\> er Prog.eaf -t -f:C:\test.txt

의 경우에는 argn은 2가 되고 args는

{"-t", "-f:C:\test.txt"} 

가 된다.


변수[편집]

변수를 선언하는 방법은 다음과 같다

new [static] [signed] <Type> [Array([num])] Name [= Init]

static을 쓸 경우에는 초기값을 무조건 정해야 하며 초기값이 정해진 뒤로는 값이 변하지 않고, 변할 수도 없다. 값을 바꾸려는 시도는 에러로 처리된다.

signed를 쓸 경우 int, float, double, long의 경우 부호가 있게 된다.

Type에 들어갈 수 있는 종류는 다음과 같다.

int [부호없는 정수], float [부호없는 고정소수], double [부호없는 부동소수], long [부호없는 긴 정수], bool [불린값, 참 혹은 거짓],
char [문자 하나], string [문자열], file [파일], class [클래스], function [함수]

배열을 선언하는 법은 두가지가 있다.

new int Array[] Ar1 = {1, 2, 3}; // 선언과 동시에 대입해야만 한다.
new int Array[3] Ar2;
Ar2 = {1, 2, 3}; // 나중에 대입해도 됨.

변수의 이름을 지을 때는 규칙이 있다.

1. 길이는 1~255자 이내
2. 예약어, 이미 지정된 변수, 함수, 클래스 등을 써서는 안된다.
3. 첫 번째 글자로 숫자가 와서는 안된다.
4. 사용할 수 있는 문자는 영어 대소문자, 숫자, _ 뿐이다.

변수를 선언할 때는 초기값을 지정할 수도 있고 지정하지 않고 후에 지정할 수도 있다.

변수를 같은 타입으로 여러 개 선언하기 위해서는 다음과 같이 한다.

new char A = 'a', B, C = 'c';

문장[편집]

C언어에서는

#include <stdio.h>
main() { printf("Hello, World\n"); }

처럼 들여쓰기를 무시한 채로 소스를 작성할 수 있지만, E언어에서는 파이썬처럼 띄어쓰기가 필수이다.

또한 모든 문장은 ;로 끝나야한다.


함수[편집]

E언어에서 함수를 선언하기 위해서는

new function Func1();

처럼 한다. 또한 함수가 선언된 뒤 함수를 정의하기 위해서는

Func1() = {
    /* 함수 내용 */
}

처럼 한다. 그리고 함수가 정의된 뒤 함수를 재정의하기 위해서는

redef Func1() = {
    /* 바뀐 내용 */
}

처럼 한다.

함수를 선언함과 동시에 정의할 수도 있는데 이것은

new function Func1() = {
    /* 함수 내용 */
}

처럼 한다.

함수에 반환값이 있을때는

new function Func_RTN() = {
    /* 함수 내용 */
} return /*자료형*/

처럼 한다.

함수에 인수를 넘겨주기 위해서는

new function Func2(int a, string b);

처럼 선언하거나 선언한 뒤 정의하면 된다. 단 함수에 인수가 들어가고 함수를 따로 정의할 경우에는

new function Func2(int a);
Func2(int b/* int a라고 쓸 경우 에러 없음*/) = {
     /* 에러 */
}

처럼 인수로 넘어오는 변수의 이름이 달라서는 안된다.

또한 함수의 인수가 변하는 가변인수도 있는데, 이것은 간단한 예로 설명하도록 하겠다.

new function Sum (int Num , ...) = {
     new VARLIST Var_List;
     new int i = 0, sum = 0;
     repeat(VARLIST_MAX(Var_List)) {
          sum += Var_List(i++); 
     }
     say("%int%\n", sum);
}
Func1(5, 1, 2, 3, 4, 5); // 15

반복, 제어문[편집]

반복문[편집]

E언어에는 다음과 같은 반복문이 있다.

for(<init>:<cond>:<then>) { } 
// init을 수행한 뒤 cond를 확인해서 참이면 블록을 실행후 then을 수행한 뒤 다시 cond확인, cond가 거짓 이면 탈출
while(<cond>) { }
// cond가 참이면 블록을 실행
do { } while(<cond>);
// 블록을 실행한 뒤 cond가 참이면 다시 블록을 실행, 거짓이면 탈출
repeat(<num>) { }
// num번 블록을 실행한다.

제어문[편집]

E언어에는 다음과 같은 제어문이 있다.

if(<cond>) { /*1*/ } else { /*2*/}
// cond가 참이면 1을 거짓이면 2를 실행. else if처럼 사용 가능
switch(<var>) {
     case <cond>:
          /* 실행 */
     default:
          /* 해당 없음 */
} // var가 cond와 같으면 그 밑에 들여쓰기 된 블록을 실행, 모든 case에도 해당되지 않으면 default블록 실행
<LABLE>: // goto에서 이 레이블을 지정하면 이곳으로 와서 소스를 실행
goto <LABLE>; // 선언된 레이블로 이동

연산자[편집]

E언어에는 다음과 같은 연산자들이 있다.

+-*/% 			: 산술 연산자
=			: 대입 연산자
> >= < <= == !=		: 관계 연산자
&& || !			: 논리 연산자
++ -- 			: 증감 연산자
(cond) ? t : f		: 삼항 조건 연산자
& | ~ ^ ~& ~| ~^ << >>	: 비트 연산자

연산자들의 순서는 다음과 같다.

()[]
! ~ ++ --
* / %
+ -
>> <<
< <= > >=
== !=
& ^ | ~& ~| ~^
&& ||
? :
= += -= *= /= %= &= ^= |= ~&= ~|= ~^= >>= <<=

클래스[편집]

클래스의 선언은 다음과 같이 한다.

new class Class1;

클래스의 정의도 함수의 정의처럼 선언과 함께 할 수 있다.

new class Class1 = {
     new signed int SINT1;
     new int UINT1 = 1; // 초기값 설정 가능
     new function FUNC1;
}

클래스 내부에 선언만 되어있는 함수는

Class1.FUNC1 = {
     /* 함수 내용 */
}

과 같이 정의한다.

클래스를 생성할때는

new Class1 CL1;

처럼 생성한다.
클래스를 생성하면서 내부의 값을 바꾸기 위해서는

new Class1 CL2 { 2, 3, };

처럼 한다.
클래스를 파괴할때는

DestroyClass(CL2);

처럼 한다. (DestroyClass()는 내장함수이다.)
클래스를 생성하거나 파괴할때, 같은 클래스끼리 연산할 때 특정한 함수를 사용되게 할 수 있는데, 이것은 예를 들어서 설명하겠다.

new class Class3 = {
     new int A;
     new int B;
     new function __MAKE__ = {
          say("클래스 %string% 생성\n", __NAME__);
     }
     new function __DEL__ = {
          say("클래스 %string% 파괴\n", __NAME__);
     }
     new function __OPER_=__ = {
          __LEFT__.A = __RIGHT__.A;
          __LEFT__.B = __RIGHT__.B;
     }
}
new Class3 CL3_1, CL3_2; // "클래스 CL3_1 생성" "클래스 CL3_2 생성"
CL3_1 = { 1, 3 };
CL3_2 = CL3_1; 
say("%int%, %int%, %int%, %int%\n", CL3_1.A, CL3_2.A, CL3_1.B, CL3_1.B);
DestroyClass(CL3_1); // "클래스 CL3_1 파괴"
DestroyClass(CL3_2); // "클래스 CL3_2 파괴"

eaf파일[편집]

eaf파일은 es 파일을 ec.exe로 컴파일 했을때 생기는 파일이다. 이 파일은 er.exe로 돌릴수 있다.

전처리기[편집]

예제소스[편집]

%with stio.eh
main() {
   new int tNum = 10;
   say("Hello, E Script?\n");
   say("tNum의 값 : %int%\n", tNum);
   ask("%int%", tNum);
   say("tNum의 값 : %int%\n", tNum);
}

처리 방법[편집]

헤더 파일 목록[편집]

ec.exe는 최초로 main 파일을 읽은 뒤 with문으로 포함된 eh파일의 목록을 작성한다.

크기(byte) 내용
2 헤더의 시작을 알림 'h','s'
2 헤더 파일의 개수 1(0x0001)
4 헤더 위치의 길이 14(0x00000E)
n 헤더의 위치 "%with%/stio.eh"
2 헤더의 종료를 알림 'h','e'

main의 헤더목록을 모두 작성한 뒤에는 헤더 내부의 헤더를 확인한다. (stio.eh에는 포함된 헤더가 없음)

함수 목록[편집]

이렇게 반복해서 모든 헤더의 목록을 작성한 뒤에는 소스 내부에서 사용된 함수의 목록을 만든다.

크기(byte) 내용
2 함수의 시작을 알림 'f', 's'
1 함수의 이름 길이 3(0x03)
n 함수의 이름 "say"
1 함수의 매개변수 갯수 2(0x02)
n 매개변수 1의 타입 "string"
n 매개변수 2의 타입 "..."
2 함수의 끝을 알림 'f', 'e'
2 함수의 시작을 알림 'f', 's'
1 함수의 이름 길이 3(0x03)
n 함수의 이름 "ask"
1 함수의 매개변수 갯수 2(0x02)
n 매개변수 1의 타입 "string"
n 매개변수 2의 타입 "..."
2 함수의 끝을 알림 'f', 'e'