在设计字节码解释器时,这些天是否有关于堆栈或三种地址格式(或其他什么?)更好的共识?我正在考虑这些考虑因素:
目标语言是一种非常类似于Javascript的动态语言.
性能很重要,但目前开发速度和可移植性更是如此.
因此,实施将严格地作为解释者; 资源许可后,JIT编译器可能会更晚出现.
口译员将用C语言编写.
在llvm教程和示例中,编译器通过这样的调用输出LLVM IR
return Builder.CreateAdd(L, R, "addtmp");
Run Code Online (Sandbox Code Playgroud)
但许多口译员写得像这样:
switch (opcode) {
case ADD:
result = L + R;
break;
...
Run Code Online (Sandbox Code Playgroud)
您将如何提取每个代码片段以使用LLVM进行JIT而无需在LLVM IR中重新实现每个操作码?
我被告知如果我在ANSI-C中编码以按照将要使用的变量的顺序声明,断言指针不是null并且索引在边界内,并且在使用变量之前初始化.
如果我声明一个const,我可以在一个断言和代码块之后初始化它吗?在Java中,最终初始化必须在声明时进行,但是通过ANSI-C实现它是否一致,我可以初始化const一次但不一定在声明时?
我正在用nim(在编写本文的时候仍称为nimrod),通过在语言中编写Brainfuck解释器来玩弄它.没有实现循环,我有:
import os, unsigned
const RamSize = 200
type
TRam = array[0..RamSize, int]
var
ram : TRam
ip : int = 0
dp : int = 0
proc readCode(path: string) =
var
f : TFile = open(path)
i : int = 0
while i < RamSize and not EndOfFile(f):
ram[i] = ord(readChar(f))
inc(i)
proc main(path: string) =
readCode(path)
while ip < RamSize:
case chr(ram[ip])
of '>' : inc dp
of '<' : dec dp
of '+' : inc …Run Code Online (Sandbox Code Playgroud) interpreter language-implementation brainfuck nimrod nim-lang
所有语言如何实现异步回调?
例如,在C++中,需要一个"监视线程"来启动std::async.如果它在主线程中启动,则必须等待回调.
std::thread t{[]{std::async(callback_function).get();}}.detach();
Run Code Online (Sandbox Code Playgroud)
VS
std::async(callback_function).get(); //Main thread will have to wait
Run Code Online (Sandbox Code Playgroud)
那么JavaScript中的异步回调呢?在JS中大量使用回调... V8如何实现它们?V8是否会创建大量线程来监听它们并在收到消息时执行回调?或者它是否使用一个线程来监听所有回调并保持刷新?
例如,
setInterval(function(){},1000);
setInterval(function(){},2000);
Run Code Online (Sandbox Code Playgroud)
V8是否创建了2个线程并监视每个回调状态,或者它有一个池来监视所有回调?
LOOP 一词被描述为“解析所有未解析的 LEAVE 事件的目的地”。(强调我的)
与 IF ... ELSE ... THEN 的前向引用数始终为 1 不同,LOOP 对 LEAVE 的数量没有限制。那怎么实施呢?
我想到的一种方法是始终将 LEAVE 的数量保持在堆栈顶部。每个 LEAVE 都会增加此计数器并将其置于其下。LOOP 从顶部读取计数器并解析那么多引用。但这似乎是一个便宜的伎俩。
真正的 Forth 系统如何实现这种循环?我不需要 teh codez(将 Forth 作为学习经验实施),只需要概念。
我只是用不同的语法在Python中进行实验,以便将生成器作为参数传递给函数,我意识到虽然我一直这样做,
>>> sum((j for j in xrange(5)))
10
Run Code Online (Sandbox Code Playgroud)
这也有效:
>>> sum(j for j in xrange(5))
10
Run Code Online (Sandbox Code Playgroud)
这是在Linux上的Python 2.6.6上测试的.引擎盖下发生了什么?它只是语法糖吗?毕竟,通常一个解包的生成器是解释器无法解读的:
>>> j for j in xrange(5)
File "<stdin>", line 1
j for j in xrange(5)
^
SyntaxError: invalid syntax
Run Code Online (Sandbox Code Playgroud) 我目前正在阅读实现函数式语言: SPJ的一个教程和我将在这个问题中引用的(子)章节是3.8.7(第136页).
第一个注意事项是,遵循本教程的读者尚未实现ECase表达式的C方案编译(即出现在非严格上下文中的表达式).
提出的解决方案是转换Core程序,以便ECase表达式根本不会出现在非严格的上下文中.具体来说,每次这样的事件都会创建一个新的超级组合器,其中只有一个变量,该变量的主体对应于原始的ECase表达式,并且该事件本身会被对该超级组合器的调用所替换.
下面我将介绍一个(略微修改过的)1的转换示例
t a b = Pack{2,1} ;
f x = Pack{2,2} (case t x 7 6 of
<1> -> 1;
<2> -> 2) Pack{1,0} ;
main = f 3
== transformed into ==>
t a b = Pack{2,1} ;
f x = Pack{2,2} ($Case1 (t x 7 6)) Pack{1,0} ;
$Case1 x = case x of
<1> -> 1;
<2> -> 2 ;
main = f 3
Run Code Online (Sandbox Code Playgroud)
我实现了这个解决方案,它就像魅力一样,就是输出Pack{2,2} 2 Pack{1,0} …
haskell functional-programming compilation language-implementation lazy-evaluation
cppref给出了可能的实现std::same_as:
namespace detail {
template<class T, class U>
concept SameHelper = std::is_same_v<T, U>;
}
template<class T, class U>
concept same_as = detail::SameHelper<T, U> && detail::SameHelper<U, T>;
Run Code Online (Sandbox Code Playgroud)
为什么不实现如下:
template<class T, class U>
concept same_as = std::is_same_v<T, U> && std::is_same_v<U, T>;
Run Code Online (Sandbox Code Playgroud)
甚至更短:
template<class T, class U>
concept same_as = std::is_same_v<T, U>;
Run Code Online (Sandbox Code Playgroud)