사용자: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' |