2008-10-11 7 views
16

JavaScript는 매크로 (Lisp 스타일의 매크로)를 지원하지 않지만 누군가가 매크로를 시뮬레이션 할 수있는 솔루션을 가지고 있는지 궁금합니다. 나는 그것을 봤고, 해결책 중 하나는 eval()을 사용하여 제안했지만 그가 말했듯이 꽤 비싸다.JavaScript로 매크로를 시뮬레이트하려면 어떻게해야합니까?

정말 멋진 광고는 아닙니다. 나는 그들과 함께 간단한 것을하고 싶다. 디버깅이 훨씬 더 어려워서는 안됩니다.

답변

-2

자바 스크립트가 해석됩니다. Eval은 Javascript에서 그 이상의 비용이 드는 것은 아닙니다.

+0

틀렸어! 제임스,이 질문에 대해 읽어보십시오. http : //stackoverflow.com/questions/86513/why-is-using-javascript-eval-function-a-bad-idea#87260 오해의 소지가있는 진술을하기 전에 의견을 확인하십시오. eval에 전달 된 문자열은 eval이 호출 될 때마다 구문 분석되거나 해석되어야합니다! – Ash

+0

예, eval이 호출 될 때마다 eval에 전달 된 문자열을 파싱해야합니다.하지만 자바 스크립트의 모든 다른 행에서도 마찬가지입니다. 그것이 통역사가 작동하는 방식입니다. 당신이 연결 한 대답에 관해서는, 그는 결코 속도를 언급하지 않습니다. "읽기 쉽고 잠재적으로 버그가 적은 것" –

+2

브라우저에서 Javascript를 사용했을 때 아마도 2000 년 전후로 말했을 것입니다. 일반 자바 스크립트 코드 (즉, 비표준 코드)에 심각한 최적화가 적용되고 있으며 이는 계속 될 것입니다. 모든 언어의 문자열에있는 코드는 가까운 곳에서도 최적화 할 수 없습니다. – Ash

22

parenscript을 사용할 수 있습니다. Javascript 매크로를 제공합니다.

나는 내가 CPU 에뮬레이션을위한 매크로이 방법으로 시뮬레이션 자바 스크립트 게임 보이 에뮬레이터 작성한
+0

-1 parenscript가 2008 년에는 괜찮 았지만 실제로 ClojureScript를 사용해야합니다. –

+0

다른 솔루션 ... Parenscript는 ClojureScript와 달리 다소 얇은 레이어입니다. –

+2

다른 언어가 아닌 다른 언어들도 있습니다. –

5

:

매크로 코드 (함수가 매크로 코드 문자열을 반환) :

function CPU_CP_A(R,C) { // this function simulates the CP instruction, 
    return ''+    // sets CPU flags and stores in CCC the number 
    'FZ=(RA=='+R+');'+  // of cpu cycles needed 
    'FN=1;'+ 
    'FC=RA<'+R+';'+ 
    'FH=(RA&0x0F)<('+R+'&0x0F);'+ 
    'ICC='+C+';'; 
} 

사용을 코드가 "즉석에서"생성되도록 "매크로"우리는 지금

OP[0xB8]=new Function(CPU_CP_A('RB',4)); // CP B 
OP[0xB9]=new Function(CPU_CP_A('RC',4)); // CP C 
OP[0xBA]=new Function(CPU_CP_A('RD',4)); // CP D 
OP[0xBB]=new Function(CPU_CP_A('RE',4)); // CP E 
OP[0xBC]=new Function('T1=HL>>8;'+CPU_CP_A('T1',4)); // CP H 
OP[0xBD]=new Function('T1=HL&0xFF;'+CPU_CP_A('T1',4)); // CP L 
OP[0xBE]=new Function('T1=MEM[HL];'+CPU_CP_A('T1',8)); // CP (HL) 
OP[0xBF]=new Function(CPU_CP_A('RA',4)); // CP A 

와트 ... 함수가 호출하거나 각 istruction에 대한 반복 많은 코드를 작성할 필요가 없습니다 전자는 다음과 같이 에뮬레이트 코드를 실행할 수 있습니다

OP[MEM[PC]](); // MEM is an array of bytes and PC the program counter 

는 희망이 도움이 ...

+2

에뮬레이터의 소스 코드는 어디서나 구할 수 있습니까? –

+1

'new Function (string)'은'eval()'문맥이므로'eval()'과 같은 성능 특성을 가지고 있습니다. – Havvy

+1

사실이라고 생각하지 않습니다. 평가 일 수 있지만 평가는 한 번만 발생합니다. 일단 그것이 함수라면, 정상 함수 속도로 여러 번 실행해야합니다. –

3
function unless(condition,body) { 
    return 'if(! '+condition.toSource()+'()) {' + body.toSource()+'(); }'; 
} 


eval(unless(function() { 
    return false; 
    }, function() { 
    alert("OK"); 
})); 
+0

나쁜 생각은 아니지만, 슬프게도이 솔루션은 평가와 2x 함수 정의를 너무 많이 추가합니다. +1 시도. –

+1

매크로는 COMPILE 시간에 확장되므로 JavaScript에 컴파일 단계를 추가하거나 매크로를 잊어 버릴 필요가 있습니다. 우리는 eval() 함수 만 호출하여 JavaScript를 컴파일 할 수 있으므로 어쨌든 eval()이 필요합니다. –

+0

매크로는 더 많은 consise와 표현형 코드를위한 구문 설탕입니다. 그들은 당신이 할 수있는 일의 유형을 이론적으로 증가시키지 않습니다. 컴파일 시간에 한 번만 소비되므로 런타임 비용이 0이됩니다. 여기 예제 실패 : eval은 매번 호출되며 코드는 동등한 javascript를 직접 작성하는 것보다 더 장황하고 덜 쓸모 있습니다. 매크로를 유용하게 사용하려면 unless ('false', 'alert ("OK")')와 같은 구문으로 사용할 수 있어야합니다. –

10

하나는 지금 자바 스크립트에 Clojure에서 컴파일하고 그런 식으로 매크로를 얻을 ClojureScript를 사용할 수 있습니다. 참고 ClojureScript는 Google Closure를 사용합니다.

5

LispyScript은 매크로를 지원하는 Javascript로 컴파일되는 최신 언어입니다. 그것은 트리 구문과 같은 Lisp을 가졌지 만 동일한 자바 스크립트 의미를 유지합니다. 면책 조항 : 저자는 LispyScript입니다.

+0

LispyScript는 동형 언어 (Scheme 및 Common Lisp과 같은)입니까? –

+0

예 LispyScript는 호모 이코 닉입니다. 여기의 문서를 참조하십시오. http://lispyscript.com – Santosh

+0

LispyScript는 ParenScript와 어떤 식 으로든 관련이 있습니까? 그들은 자바 스크립트로 컴파일하는 Lisp 방언이기 때문에 저와 매우 비슷하게 보입니다. http://common-lisp.net/project/parenscript/ –

20

Mozilla 라이브러리 (SweetJS)는 JavaScript로 매크로를 시뮬레이트하도록 설계되었습니다. 예를 들어, SweetJS를 사용하여 function 키워드를 def으로 바꿀 수 있습니다.

관련 문제