태터데스크 관리자

도움말
닫기
적용하기   첫페이지 만들기

태터데스크 메시지

저장하였습니다.

Test : http://www.chobocho.com/javascript/lisp.html

Github : https://github.com/chobocho/SmallLisp


Javascript 로 만든 Small LIsp


Small Lisp 만들기

자바스크립트를 공부하면서 간단한 lisp interpreter를 만들어 보기로 하고,
구글링을 통해서 찾은 사이트 http://norvig.com/lispy.html를 참고하여서 만들어 보았다.

1. 목 표

아래 코드를 실행 하여 결과를 출력

(define pi 3)  
(if (= pi 3) (+ 4 5) (* 4 5 ))  
(define twice (lambda (x) (* 2 x)))  
(twice 2)  
(define forth (lambda (x) (* (twice x) (twice x))))  
(forth 2)  
(define fact (lambda (n) (if (<= n 1) 1 (* n (fact (- n 1))))))  
(fact 16)  
(fact (forth 2))  

2. lisp test를 위한 입력용 list.html 제작

<HTML>
<head>
<title>Small lisp</title>

<script language="JavaScript" src="lisp.js"></script> 

<script language="JavaScript">
function Run(form) { 
    form.result_view.value = main(form.source_view.value); 
}

function ClearForm(form) { 
    form.result_view.value = "";
    form.source_view.value = "";    
}

</script>
</head>
<body>

<!------------------------------------------------------------------
// 입력양식
------------------------------------------------------------------->
<FORM name=source_code>
    <TABLE cellSpacing=0 borderColorDark=white align=center borderColorLight=black border=1>
        <TR>
            <TD align="center">
            [ Lisp source ]
            </TD>
            <TD align="center">
            [ 결과 (Result) ]
            </TD>    
        </TR>
        <TR>
            <TD width=160 height=40>
                <SPAN style="FONT-SIZE: 9pt"><TextArea name="source_view" cols="50" rows="20"></textArea> </SPAN>
            </TD>
            <TD width=80 height=40>
                <SPAN style="FONT-SIZE: 9pt"><TextArea name="result_view" cols="20" rows="20"></textArea> </SPAN>
            </TD>
        </TR>
        <TR>
            <TD align="center" width=246 colSpan=2 height=25>
                <SPAN style="FONT-SIZE: 9pt"><INPUT type="button" value="Run", onClick="Run(this.form)"> </SPAN>
                <SPAN style="FONT-SIZE: 9pt"><INPUT type="button" value="Clear", onClick="ClearForm(this.form)"> </SPAN>
            </TD>
        </TR>
        <TR>
            <TD width=240 colSpan=2>
                Example<br>
                (+ 1  2  3)<br>
            </TD>
        </TR>         
    </TABLE>
 </FORM>

</body> 
</HTML>

3. Small Lisp 제작

3.1 지원 할 명령어 리스트

Javascript 학습을 목적으로 만든 것이이서 최소한의 명령어만을 지원한다.

  • 1) +, -. *, /
  • 2) <. >. =. <=. >=
  • 3) define, if
  • 4) lambda (* 쉬운 구현을 위하여 lambda의 인자로 lamdba 함수는 올 수 없도록 제한 함)

3.2 제작 순서

  • 1) +, -. *, /
  • 2) <. >. =. <=. >=
  • 3) define, if
  • 4) lambda

3.3 사칙 연산 계산 ( +. -. *. / )

먼저 (+ 5 5)를 처리하는 코드를 만들어 보자.
먼저 (+ 5 5)를 파싱을 해주어야 한다. 이때, 파서를 따로 제작하지 않고,
javascript string 객체에서 지원하는 메소드를 이용한다.

3.3.1 space 기준으로 자르기 위하여, ( )를 ‘ ( ’ 와 ‘ ) ’ 로 앞뒤에 space를 붙여준다.

replace( /(/g, " ( " );
replace( /)/g, " ) " );
그러나, 구문 제일 앞의 ‘ (’ 와 ‘) ’의 스페이스는 trim()을 이용해 제거를 해주어야 한다.
그렇지 않으면, 파싱된 Token에 “ ”가 구문의 제일 앞과 뒤에 추가 된다.
이걸 정리하면 아래와 같은 코드가 나오고,

function main(args) {
    //Tokenize
    source_code = args.replace(/\(/g, " ( ").replace(/\)/g, " ) ").trim().split(/\s+/);
    return source_code;
}

list.html 에서 아래와 같이 입력시에 ( + 1 2 3 )
아래와 같은 결과를 얻을 수 있다.
(,+,1,2,3,)

3.3.2 소스를 읽어서 ( ) 로 분리한다.

( ) 를 기준으로 파싱을 하기 위한 read_from_tokens() 함수를 만든다.
'(' 를 만나면, ')'를 만날 때 까지 값을 읽어서 그 값을 하나의 리스트에 저장한다.
')'를 만나면 리스트를 통째로 하나의 인자로 input 리스트에 인자로 넣는다.

function main(args) {

    var Result = "";

    //Tokenize
    source_code = args.replace(/\(/g, " ( ").replace(/\)/g, " ) ").trim().split(/\s+/);

    tokens = [];
    read_from_tokens(source_code, tokens);

    return tokens;
}


function read_from_tokens(input, output) {
    token = input.shift();

    switch(token) {
        case undefined:
            output.pop();
            break;

        case '(':
            var list = [];
            while (input[0] != ')') {
                read_from_tokens(input, list);
            }
            input.shift(); // Remove ')'
            output.push(list);
            break;

        case ')':
           console.log("Error : Start with ')'!");
            break;

        default:
            if ( isDigit(token.charAt(0))) {
                output.push(parseInt(token));
            } else {
                output.push(token);
            }
            break;
    } 
}

function isDigit ( ch )
{
    if ("0123456789".indexOf(ch) != -1)
        return true;
    return false;
}

list.html 에서 아래와 같이 입력시에
( + 1 2 3 )
아래와 같은 결과를 얻을 수 있다.
+,1,2,3


'Coding > JavsScript 삽질기' 카테고리의 다른 글

Timer  (0) 2016.09.29
Samll lisp by Javascript  (0) 2016.09.12
Chobocho Calc 1  (1) 2016.04.23
글자수 세는 자바 스크립트  (0) 2011.11.15
Posted by chobocho
def getDecimal(q, size):
    
    if (q < 2):
        return -1
    
    p = 10
    result = "0."
    
    for i in range(size):
        m = p % q
        
        result += str(int(p / q))
        if (m == 0):
            break;
        else:
            p = m * 10
    
    return result
    

    
for i in range(2, 10):
    print(str(i) + " : " + getDecimal(i, 100) )


2 : 0.5

3 : 0.3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333

4 : 0.25

5 : 0.2

6 : 0.1666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666

7 : 0.1428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428

8 : 0.125

9 : 0.1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111

'Coding > Python 삽질기' 카테고리의 다른 글

[Python] 진법 변환  (0) 2016.12.27
단위분수를 소수로 변환하기  (0) 2016.09.07
[Notepad++] Python 실행하기  (0) 2016.08.28
Cython 설치  (3) 2013.12.15
Posted by chobocho
1. 배치파일 작성

[ python.bat ]

C:\Users\sje\AppData\Local\Programs\Python\Python35-32\python.exe "%1" 



2. Notepad++ 실행 -> 실행


C:\Work\python.bat $(FULL_CURRENT_PATH)

 




Posted by chobocho

일찍 퇴근한 기념으로 업데이트한 Color match.

이제 S7에서도 동작한다 ^^




Posted by chobocho

지극히 개인적인 용도로 쓰는 메모앱을 업데이트 했다.

좋은 컴퓨터(?)로 작업하니, 생각보다 빨리 마무리 되었다.



'Coding > Java 삽질기' 카테고리의 다른 글

[Android] Image match game ( V 0.627 )  (0) 2016.08.25
SimpleDraw update  (0) 2016.08.23
Android studio 디바이스 연결  (0) 2016.08.20
Tetris  (0) 2016.03.17
Posted by chobocho

Android studio에서 안드로이드 폰(갤럭시)이 인식이 안될때


1) 구글에서  Samsung USB driver 를 찾아서 설치

2) 단말기에서 USB debugging 모드 켜기

3) Android studio에서 Tools > Android > Enable ADB Integration 체크




'Coding > Java 삽질기' 카테고리의 다른 글

SimpleDraw update  (0) 2016.08.23
Android studio 디바이스 연결  (0) 2016.08.20
Tetris  (0) 2016.03.17
1. 온라인 테트리스 만들기 ( 이클립스 설치 )  (0) 2014.01.03
Posted by chobocho
TAG Android

arr[k >> 5] |= (1 << (k & 31));

arr[k >> 3] |= (1 << (k & 7));

'Coding > C/CPP 삽질기' 카테고리의 다른 글

Quick sort  (0) 2017.07.13
Bit 연산 정리  (0) 2016.08.20
가장 넓은 직사각형 구하는 알고리즘 ( O(MN) )  (0) 2016.04.13
printf로 디버깅 하기  (0) 2016.04.13
Posted by chobocho

2016년 목표 중 하나인 Javascript 계산기를 만들기 시작했다


Chrome의 디버깅 기능을 첨 써보고 감동 받았다. ^^;



'Coding > JavsScript 삽질기' 카테고리의 다른 글

Samll lisp by Javascript  (0) 2016.09.12
Chobocho Calc 1  (1) 2016.04.23
글자수 세는 자바 스크립트  (0) 2011.11.15
Google chart API를 이용한 QR CODE 생성기  (3) 2010.11.30
Posted by chobocho

가장 넓은 직사각형 구하는 알고리즘 ( O(MN) )


/*
From :
http://stackoverflow.com/questions/7245/puzzle-find-largest-rectangle-maximal-rectangle-problem
*/

int findMaxRect (int rect[XSIZE][YSIZE]) {
	int ret = 0;
	unsigned int x = 0, y = 0, k = 0;
	int sum[YSIZE+1] = { 0, };
	int stack[YSIZE][2] = { 0, };
	int stIdx = -1;
	int width = 0;
	int y0 = 0, w0 = 0, tempArea = 0;
	
	for ( x = 0; x < XSIZE; ++x ) { 
		for ( y = 0; y <= YSIZE; ++y ) {
			sum[y] = rect[y][x] ? ++sum[y] : 0;
		}
		sum[YSIZE] = 0;
		width = 0;
		stIdx = -1;
		for ( y = 0; y <= YSIZE; ++y) {
			if ( sum[y] > width ) {
				stack[++stIdx][0] = y;
				stack[  stIdx][1] = width;
				width = sum[y];				
			} 
			else if ( sum[y] < width ) {

				while(1) {
					y0 = stack[stIdx  ][0];
					w0 = stack[stIdx--][1];
					tempArea =  width * (y - y0);
				  
					ret = tempArea > ret ? tempArea : ret;

					width = w0;
					if( sum[y] >= width) break;
				} 
				width = sum[y];
				if ( width != 0 ) {
					stack[++stIdx][0] = y0;
					stack[  stIdx][1] = w0;	
				}
			}
		}
	}	
	
	return ret;
}


'Coding > C/CPP 삽질기' 카테고리의 다른 글

Bit 연산 정리  (0) 2016.08.20
가장 넓은 직사각형 구하는 알고리즘 ( O(MN) )  (0) 2016.04.13
printf로 디버깅 하기  (0) 2016.04.13
C++ 컴파일러  (0) 2016.03.30
Posted by chobocho

#define DEBUG


#ifdef DEBUG

    #define cprintf(...) printf(__VA_ARGS__)

#else

    #define cprintf(...) 

#endif



'Coding > C/CPP 삽질기' 카테고리의 다른 글

가장 넓은 직사각형 구하는 알고리즘 ( O(MN) )  (0) 2016.04.13
printf로 디버깅 하기  (0) 2016.04.13
C++ 컴파일러  (0) 2016.03.30
Lambda function  (1) 2016.03.17
Posted by chobocho
TAG CPP, Debug, printf