解析过程中字符串作为函数

问题描述 投票:0回答:1

TL;博士

给出: Token 和语法的序列
地点:
   令牌 := 元组[名称:字符串, 值:字符串, 父项:令牌]
   语法 := Table[system.string, proc(x:Token):string]
返回:通过语法传递的标记值字符串


实现我的翻译器时,我得出的结论是我需要根据令牌执行一些操作,我知道使用条件分支实现此功能会更正确 ,但我对一种不同的方法感兴趣,在这种方法中,在收到代币的名称后,我会与其进行一些交互。

实现这一点的最简单方法

Table[system.string, proc(x:Token):string]

但是,我不满意,因为无法在编译期间生成它。或者我可以,但是我不知道如何

因为我对 php 有一点经验,所以我知道我可以使用 字符串作为函数

    function a(int $num){ 
        return $num + 3;
    }
    echo "a"(1); // 4

基于此,Nim 有没有一种方法可以允许提前声明一组函数以这种方式访问它们


或者也许您可以建议如何采取更正确的方法来解决这个问题。

algorithm templates compiler-construction nim-lang
1个回答
0
投票

也许这就是您想要的(但这是一个快速实现)

import tables
import macros, macrocache

const procs = CacheTable"procs"

macro addToProcs(def: untyped): untyped =
  procs[def.name.strVal] = def.name
  result = def

macro genTable(t: untyped): untyped =
  result = newNimNode(nnkTableConstr)
  for name, ident in procs.pairs:
    let expr = newNimNode(nnkExprColonExpr)
    expr.add newLit(name)
    expr.add quote do:
      `t`(`ident`)
    # https://internet-of-tomohiro.pages.dev/nim/faq.en#procedures-how-to-get-a-pointer-to-a-overloaded-procedureqmark
    # use a type conversion to avoid ambiguous name `add`
    result.add expr

proc add(a: int, b: int): int {.addToProcs.} =
  a + b

proc sub(a: int, b: int): int {.addToProcs.} =
  a - b

const table = toTable genTable(typeof(sub)) # here I don't use `add` because the name `add` has many overloads in the stdlib

echo table["add"](1, 2)

这是我的第一次尝试,甚至更加严厉。

import tables
import macros

macro genTable(names: static seq[string]): untyped =
  result = newNimNode(nnkTableConstr)
  for name in names:
    let expr = newNimNode(nnkExprColonExpr)
    expr.add newLit(name)
    expr.add ident(name)
    result.add expr

proc add_uniq(a: int, b: int): int =
  a + b

proc sub_uniq(a: int, b: int): int =
  a - b


let table = toTable genTable(@["add_uniq", "sub_uniq"])

echo table["add_uniq"](1, 2) # 3
© www.soinside.com 2019 - 2024. All rights reserved.