(七)Builtin Function
内置函数在解释器中存放在builtins 哈希表中
var builtins = map[string]*object.Builtin{"len": &object.Builtin{Fn: func(args ...object.Object) object.Object {if len(args) != 1 {return newError("wrong number of arguments. got=%d, want=1", len(args))}switch arg := args[0].(type) {case *object.String:return &object.Integer{Value: int64(len(arg.Value))}case *object.Array:return &object.Integer{Value: int64(len(arg.Elements))}default:return newError("argument to `len` not supported, got %s", args[0].Type())}},
作者在这一章写了好多莫名奇妙的逻辑…
比如上面的内置函数,明明修改一下返回值即可作为编译器的参照,但是又要重写一遍,还拿切片来维护…
其实内置函数的实现很简单的,当遇到函数调用,分辨是定义函数还是内置函数,进行不同调用即可;
怎么分辨呢?编译器解析到ast.Identifier 时会查找符号表,得到当前变量的作用范围,如果是GlobalScope,c.emit(code.OpGetGlobal, s.Index) 而内置函数和普通函数的区别就在这儿!
case *ast.Identifier:symbol, ok := c.symbolTable.Resolve(node.Value)if !ok {return fmt.Errorf("undefined variable %s", node.Value)}c.loadSymbol(symbol)func (c *Compiler) loadSymbol(s Symbol) {switch s.Scope {case GlobalScope:c.emit(code.OpGetGlobal, s.Index)case LocalScope:c.emit(code.OpGetLocal, s.Index)case BuiltinScope:c.emit(code.OpGetBuiltin, s.Index)}
}
我们应该设置新的Scope关于Builtin 来识别Builtin Function
const (// ...OpGetBuiltin
)var Definitions = map[Opcode]*Definition {// ...OpGetBuiltin: {"OpGetBuiltin", []int{1}},
}
OpGetBuiltin 也要有参数位,因为内置函数会有不同的参数要求;
虚拟机执行如下:
case code.OpCall:numArgs := int(code.ReadUint8(ins[ip+1:]))vm.currentFrame().ip += 1err := vm.executeCall(int(numArgs))if err != nil {return errcase code.OpGetBuiltin:builtinIndex := code.ReadUint8(ins[ip+1:])vm.currentFrame().ip += 1definition := object.Builtins[builtinIndex]err := vm.push(definition.Builtin)if err != nil {return err}func (vm *VM) executeCall(numArgs int) error {callee := vm.stack[vm.sp-1-numArgs]switch callee := callee.(type) {case *object.CompiledFunction:return vm.callFunction(callee, numArgs)case *object.Builtin:return vm.callBuiltin(callee, numArgs)default:return fmt.Errorf("calling non-function and non-built-in")}
}func (vm *VM) callBuiltin(builtin *object.Builtin, numArgs int) error {args := vm.stack[vm.sp-numArgs : vm.sp]result := builtin.Fn(args...)vm.sp = vm.sp - numArgs - 1if result != nil {vm.push(result)} else {vm.push(nil)}return nil
}
其实和正常的调用一样,只不过内置函数调用的是提供好的接口,定义函数则是模拟调用过程!
(当然了,内置函数要先在REPL 前于全局符号表中定义方可使用)
(七)Builtin Function相关推荐
- warning incompatible implicit declaration of built-in function 'printf'
利用arm交叉编译器编译一个简单的c程序出现 warning :incompatible implicit declaration of built-in function 'printf'错误 原 ...
- FastApi报错 Invalid args for response field! Hint: check that <built-in function id> 。。。解决方法
今天运行项目发现运行报错,错误内容是: Invalid args for response field! Hint: check that <built-in function id> i ...
- Builtin function
发现 Builtin function 可以用来计算十进制数中1的个数:返回1的个数是奇数还是偶数:返回开头0的个数:返回结尾0的个数. 参考链接: // C program to illustrat ...
- [Warning] incompatible implicit declaration of built-in function ‘memset‘
[Warning] incompatible implicit declaration of built-in function 'memset' 原因是memset第一个参数是void * 类型,我 ...
- MATLAB笔记:一些自嵌函数/built-in function
文章目录 strvcat(不推荐)垂直串联字符串 ind2sub 索引值转换为下标 squeeze gcd(求最大公约数) fullfile physconst typecast(在不更改基础数据的情 ...
- set built-in function
集合类型 集合对象是一组无序排列的可哈希的值,集合可以作为字典的键.因为集合是无序的,不可以为集合创建索引或执行切片操作,也没有键可以用来获取元素的值. 集合有两种不同的类型,可变集合和不可变集合.可 ...
- warning: incompatible implicit declaration of built-in function ‘exit’
出现这个错误,一般是程序中某个函数没有include相关的文件. EG. 出现这个错误是因为要使用exit()应该包含stdlib.h文件 转载于:https://www.cnblogs.com/wi ...
- Python编程核心内容 ---- Function(函数)
什么"大事"呢?下面将要介绍Python编程的核心内容之一--函数. 对于Python编程,函数的重要性不言而喻.重要的事情讲三遍:函数实在是太重要,太关键了. 引入函数 之前,我 ...
- php七牛分片上传_ThinkPHP实现JavaScript上传大视频到七牛云实例
1.通过Composer安装七牛云PHP SDK,官方文档 2.后端核心代码如下: use Qiniu\Auth as Auth; use Qiniu\Config; use Qiniu\Storag ...
最新文章
- 管理-Tomcat和Resin如何配置对指定后缀文件(如:.pptx)下载支持
- Binder相关面试总结(七):AIDL内部的实现原理是什么
- 【云周刊】第132期:走近40+世界级AI专家!第三届中国人工智能大会资料分享...
- Vagrant配置虚拟机
- 一文详解神经网络模型
- The fall of RNN / LSTM
- 翻币问题pascal程序
- 神经网络 | 网络优化-线性神经网络-delta学习规则-梯度下降法(线性神经网络-异或问题Python源代码)
- oracle里查询表的语句,Oracle查询用户所有表的语句
- 把VS Code打造成Java开发IDE,也挺爽!
- sublime配置python编译环境及代码补全功能
- 函数作为参数传递至函数内部进行调用
- more than one device and emulator
- mysql where range_MYSQL explain详解之range
- C语言-数组练习题(附答案)
- STM32中AD采样的三种方法分析
- 干货 | 携程Elasticsearch数据同步实践
- croeldraw基本知识点
- Error: L6218E: Undefined symbol vApplicationGetIdleTaskMemory (referred from tasks.o).
- 【Redis】布隆过滤器