当前位置: 首页 > news >正文

沈阳网站建设那家好百度站长工具抓取诊断

沈阳网站建设那家好,百度站长工具抓取诊断,如何做网站小编,鹏达建设集团有限公司网站文章目录 emacs源码分析&#xff08;七&#xff09;自己动手把emacs的DEFUN宏抠出来 <2024-01-07 周日> emacs源码分析&#xff08;七&#xff09; 这DEFUN宏就像胶水一样&#xff0c;它把c代码和emacs-lisp代码给联系起来。但是DEFUN宏看着怪恐怖的有没有&#xff01;…

文章目录

  • `emacs`源码分析(七)
    • 自己动手把`emacs`的`DEFUN`宏抠出来

<2024-01-07 周日>

emacs源码分析(七)

DEFUN宏就像胶水一样,它把c代码和emacs-lisp代码给联系起来。但是DEFUN宏看着怪恐怖的有没有!

/* This version of DEFUN declares a function prototype with the rightarguments, so we can catch errors with maxargs at compile-time.  */
#define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \SUBR_SECTION_ATTRIBUTE                                            \static union Aligned_Lisp_Subr sname =                            \{{{ PVEC_SUBR << PSEUDOVECTOR_AREA_BITS },                     \{ .a ## maxargs = fnname },                                  \minargs, maxargs, lname, {intspec}, 0}};                     \Lisp_Object fnname

自己动手把emacsDEFUN宏抠出来

为了方便理解,我把DEFUN宏给抠了出来,放在一个单独的工程里:ysouyno/t_emacs_defun,如果不想下载工程,本篇结尾会附上所有源码(仅一个文件,不到300行代码)。

关于这个工程要注意:

  1. 仅适用于windows平台,为了编译方便,很多辅助宏能省略则省略。
  2. 设置C++ Language StandardISO C++20 Standard (/std:c++20)

挑了一个最简单的emacs-lisp函数eq

DEFUN ("eq", Feq, Seq, 2, 2, 0,doc: /* Return t if the two args are the same Lisp object.  */attributes: const)(Lisp_Object obj1, Lisp_Object obj2)
{if (EQ (obj1, obj2))return Qt;return Qnil;
}

展开后的eq代码是:

static union Aligned_Lisp_Subr Seq =
{{{ PVEC_SUBR << PSEUDOVECTOR_AREA_BITS }, // struct Lisp_Subr::header{.a2 = Feq },                            // struct Lisp_Subr::function2,                                       // struct Lisp_Subr::min_args2,                                       // struct Lisp_Subr::max_args"eq",                                    // struct Lisp_Subr::symbol_name{0},                                     // struct Lisp_Subr::intspec0                                        // struct Lisp_Subr::doc}
};Lisp_Object Feq(Lisp_Object obj1, Lisp_Object obj2)
{if (EQ(obj1, obj2))return Qt;return Qnil;
}

从上可得,DEFUN有两个任务以(eq函数为例):

  1. 声明一个静态变量Seq,它应该会将要用于emacs-lisp代码中的某些地方,目前我还不清楚细节。
  2. 定义一个c函数Feq

我照着DEFUN宏展开后样子定义了一个没有使用DEFUN宏来定义的函数my-eq,它可以正常工作:

// DEFUN("my-eq", ...)
static union Aligned_Lisp_Subr Smy_eq =
{ {{ PVEC_SUBR << PSEUDOVECTOR_AREA_BITS },{.a2 = Fmy_eq },2, 2, "my-eq", {0}, 0} };
Lisp_Object Fmy_eq(Lisp_Object obj1, Lisp_Object obj2)
{if (EQ(obj1, obj2))return Qt;return Qnil;
}

备注:

  1. 有一个EXFUN宏要关注一下,这个代码我也抠出来了,它是用于声明Feq,否则编译器要报怨的:
error C2065: 'Feq': undeclared identifier
  1. emacs源代码中,大量EXFUN的函数声明在globals.h文件中。该文件的生成方法见:“emacs源码分析(一)”。

附完整代码:

// t_emacs_defun.cpp : This file contains the 'main' function. Program execution begins and ends there.
//#include <stddef.h> // for ptrdiff_t
#include <stdio.h>typedef long long EMACS_INT;
typedef EMACS_INT Lisp_Word;#define SUBR_SECTION_ATTRIBUTE/* Minimum alignment requirement for Lisp objects, imposed by theinternal representation of tagged pointers.  It is 2**GCTYPEBITS ifUSE_LSB_TAG, 1 otherwise.  It must be a literal integer constant,for older versions of GCC (through at least 4.9).  */
#if USE_LSB_TAG
# define GCALIGNMENT 8
# if GCALIGNMENT != 1 << GCTYPEBITS
#  error "GCALIGNMENT and GCTYPEBITS are inconsistent"
# endif
#else
# define GCALIGNMENT 1
#endif#define GCALIGNED_UNION_MEMBER char alignas (GCALIGNMENT) gcaligned;#if HAVE_STRUCT_ATTRIBUTE_ALIGNED
# define GCALIGNED_STRUCT __attribute__ ((aligned (GCALIGNMENT)))
#else
# define GCALIGNED_STRUCT
#endifunion vectorlike_header
{/* The main member contains various pieces of information:- The MSB (ARRAY_MARK_FLAG) holds the gcmarkbit.- The next bit (PSEUDOVECTOR_FLAG) indicates whether this is a plainvector (0) or a pseudovector (1).- If PSEUDOVECTOR_FLAG is 0, the rest holds the size (numberof slots) of the vector.- If PSEUDOVECTOR_FLAG is 1, the rest is subdivided into three fields:- a) pseudovector subtype held in PVEC_TYPE_MASK field;- b) number of Lisp_Objects slots at the beginning of the objectheld in PSEUDOVECTOR_SIZE_MASK field.  These objects are alwaystraced by the GC;- c) size of the rest fields held in PSEUDOVECTOR_REST_MASK andmeasured in word_size units.  Rest fields may also includeLisp_Objects, but these objects usually needs some special treatmentduring GC.There are some exceptions.  For PVEC_FREE, b) is always zero.  ForPVEC_BOOL_VECTOR and PVEC_SUBR, both b) and c) are always zero.Current layout limits the pseudovectors to 63 PVEC_xxx subtypes,4095 Lisp_Objects in GC-ed area and 4095 word-sized other slots.  */ptrdiff_t size;
};/* A Lisp_Object is a tagged pointer or integer.  Ordinarily it is aLisp_Word.  However, if CHECK_LISP_OBJECT_TYPE, it is a wrapperaround Lisp_Word, to help catch thinkos like 'Lisp_Object x = 0;'.LISP_INITIALLY (W) initializes a Lisp object with a tagged valuethat is a Lisp_Word W.  It can be used in a static initializer.  */#ifdef CHECK_LISP_OBJECT_TYPE
typedef struct Lisp_Object { Lisp_Word i; } Lisp_Object;
# define LISP_OBJECT_IS_STRUCT
# define LISP_INITIALLY(w) {w}
# undef CHECK_LISP_OBJECT_TYPE
enum CHECK_LISP_OBJECT_TYPE { CHECK_LISP_OBJECT_TYPE = true };
#else
typedef Lisp_Word Lisp_Object;
# define LISP_INITIALLY(w) (w)
enum CHECK_LISP_OBJECT_TYPE { CHECK_LISP_OBJECT_TYPE = false };
#endif/* This structure describes a built-in function.It is generated by the DEFUN macro only.defsubr makes it into a Lisp object.  */struct Lisp_Subr
{union vectorlike_header header;union {Lisp_Object(*a0) (void);Lisp_Object(*a1) (Lisp_Object);Lisp_Object(*a2) (Lisp_Object, Lisp_Object);Lisp_Object(*a3) (Lisp_Object, Lisp_Object, Lisp_Object);Lisp_Object(*a4) (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object);Lisp_Object(*a5) (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object);Lisp_Object(*a6) (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object);Lisp_Object(*a7) (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object);Lisp_Object(*a8) (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object);Lisp_Object(*aUNEVALLED) (Lisp_Object args);Lisp_Object(*aMANY) (ptrdiff_t, Lisp_Object*);} function;short min_args, max_args;const char* symbol_name;union {const char* intspec;Lisp_Object native_intspec;};EMACS_INT doc;
#ifdef HAVE_NATIVE_COMPLisp_Object native_comp_u;char* native_c_name;Lisp_Object lambda_list;Lisp_Object type;
#endif
} GCALIGNED_STRUCT;union Aligned_Lisp_Subr
{struct Lisp_Subr s;GCALIGNED_UNION_MEMBER
};enum pvec_type
{PVEC_NORMAL_VECTOR, /* Should be first, for sxhash_obj.  */PVEC_FREE,PVEC_BIGNUM,PVEC_MARKER,PVEC_OVERLAY,PVEC_FINALIZER,PVEC_MISC_PTR,PVEC_USER_PTR,PVEC_PROCESS,PVEC_FRAME,PVEC_WINDOW,PVEC_BOOL_VECTOR,PVEC_BUFFER,PVEC_HASH_TABLE,PVEC_TERMINAL,PVEC_WINDOW_CONFIGURATION,PVEC_SUBR,PVEC_OTHER, /* Should never be visible to Elisp code.  */PVEC_XWIDGET,PVEC_XWIDGET_VIEW,PVEC_THREAD,PVEC_MUTEX,PVEC_CONDVAR,PVEC_MODULE_FUNCTION,PVEC_NATIVE_COMP_UNIT,/* These should be last, for internal_equal and sxhash_obj.  */PVEC_COMPILED,PVEC_CHAR_TABLE,PVEC_SUB_CHAR_TABLE,PVEC_RECORD,PVEC_FONT /* Should be last because it's used for range checking.  */
};enum More_Lisp_Bits
{/* For convenience, we also store the number of elements in these bits.Note that this size is not necessarily the memory-footprint size, butonly the number of Lisp_Object fields (that need to be traced by GC).The distinction is used, e.g., by Lisp_Process, which places extranon-Lisp_Object fields at the end of the structure.  */PSEUDOVECTOR_SIZE_BITS = 12,PSEUDOVECTOR_SIZE_MASK = (1 << PSEUDOVECTOR_SIZE_BITS) - 1,/* To calculate the memory footprint of the pseudovector, it's usefulto store the size of non-Lisp area in word_size units here.  */PSEUDOVECTOR_REST_BITS = 12,PSEUDOVECTOR_REST_MASK = (((1 << PSEUDOVECTOR_REST_BITS) - 1)<< PSEUDOVECTOR_SIZE_BITS),/* Used to extract pseudovector subtype information.  */PSEUDOVECTOR_AREA_BITS = PSEUDOVECTOR_SIZE_BITS + PSEUDOVECTOR_REST_BITS,PVEC_TYPE_MASK = 0x3f << PSEUDOVECTOR_AREA_BITS
};/* This version of DEFUN declares a function prototype with the rightarguments, so we can catch errors with maxargs at compile-time.  */
#define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \SUBR_SECTION_ATTRIBUTE                                            \static union Aligned_Lisp_Subr sname =                            \{{{ PVEC_SUBR << PSEUDOVECTOR_AREA_BITS },                     \{ .a ## maxargs = fnname },                                  \minargs, maxargs, lname, {intspec}, 0}};                     \Lisp_Object fnnameenum maxargs
{MANY = -2,UNEVALLED = -1
};#define EXFUN(fnname, maxargs) \extern Lisp_Object fnname DEFUN_ARGS_ ## maxargs/* Note that the weird token-substitution semantics of ANSI C makesthis work for MANY and UNEVALLED.  */
#define DEFUN_ARGS_MANY		(ptrdiff_t, Lisp_Object *)
#define DEFUN_ARGS_UNEVALLED	(Lisp_Object)
#define DEFUN_ARGS_0	(void)
#define DEFUN_ARGS_1	(Lisp_Object)
#define DEFUN_ARGS_2	(Lisp_Object, Lisp_Object)
#define DEFUN_ARGS_3	(Lisp_Object, Lisp_Object, Lisp_Object)
#define DEFUN_ARGS_4	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object)
#define DEFUN_ARGS_5	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \Lisp_Object)
#define DEFUN_ARGS_6	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \Lisp_Object, Lisp_Object)
#define DEFUN_ARGS_7	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \Lisp_Object, Lisp_Object, Lisp_Object)
#define DEFUN_ARGS_8	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object)EXFUN(Feq, 2); // for error C2065: 'Feq': undeclared identifier
EXFUN(Fmy_eq, 2);#define lisp_h_XLI(o) (o)
#define XLI(o) lisp_h_XLI (o)
#define lisp_h_EQ(x, y) (XLI (x) == XLI (y))
#define EQ(x, y) lisp_h_EQ (x, y)#define Qt (Lisp_Object)1
#define Qnil (Lisp_Object)0/*
static union Aligned_Lisp_Subr Seq =
{{{ PVEC_SUBR << PSEUDOVECTOR_AREA_BITS }, // struct Lisp_Subr::header{.a2 = Feq },                            // struct Lisp_Subr::function2,                                       // struct Lisp_Subr::min_args2,                                       // struct Lisp_Subr::max_args"eq",                                    // struct Lisp_Subr::symbol_name{0},                                     // struct Lisp_Subr::intspec0                                        // struct Lisp_Subr::doc}
};Lisp_Object Feq(Lisp_Object obj1, Lisp_Object obj2)
{if (EQ(obj1, obj2))return Qt;return Qnil;
}
*/// error C7555: use of designated initializers requires at least '/std:c++20'
DEFUN("eq", Feq, Seq, 2, 2, 0,doc: /* Return t if the two args are the same Lisp object.  */
attributes: const)
(Lisp_Object obj1, Lisp_Object obj2)
{if (EQ(obj1, obj2))return Qt;return Qnil;
}// DEFUN("my-eq", ...)
static union Aligned_Lisp_Subr Smy_eq =
{ {{ PVEC_SUBR << PSEUDOVECTOR_AREA_BITS },{.a2 = Fmy_eq },2, 2, "my-eq", {0}, 0} };
Lisp_Object Fmy_eq(Lisp_Object obj1, Lisp_Object obj2)
{if (EQ(obj1, obj2))return Qt;return Qnil;
}int main() {printf("Feq(0, 0): %s\n", Feq(0, 0) ? "true" : "false");printf("Feq(0, 1): %s\n", Feq(0, 1) ? "true" : "false");printf("Fmy_eq(11, 11): %s\n", Fmy_eq(0, 0) ? "true" : "false");printf("Fmy_eq(10, 11): %s\n", Fmy_eq(0, 1) ? "true" : "false");
}

程序输出:

Feq(0, 0): true
Feq(0, 1): false
Fmy_eq(11, 11): true
Fmy_eq(10, 11): false
http://www.yayakq.cn/news/613192/

相关文章:

  • 企业网站推广的形式有哪些阿里巴巴做网站的电话号码
  • 云加速应用于html网站超级外链自动发布工具
  • 做一个色流网站怎么做台州专业网站设计系统
  • 如何做好网站的建设与维护网络规划设计师有用吗
  • 做网站是干啥的余姚网站推广策划案
  • 网站空间ftp下载慢百度识图搜索图片来源
  • PHP网站开发涉及的工具有哪些做电商网站需要注册什么公司
  • 门禁考勤网站建设重庆大江建设工程集团有限公司
  • 1微信网站怎么建设网站空间搭建
  • 网站域名空间管理网站设计论坛
  • 做网站让人来注册学做家庭树网站
  • 普洱市建设局网站游戏门户网站有哪些
  • 企业查询官网入口查询免费郑州关键词优化平台
  • 最便宜的外贸自建站平台济南优化网站方法
  • 爱站网关键字查询餐饮公司的网站建设
  • 网站开发技术的现状及发展趋势万网网站模板购买
  • 网站建设理论基础oppo应用商店下载
  • 旅游网站的功能及建设建筑安全网
  • wordpress企业站源码电子商务网站建设的书
  • 看守所加强自身网站建设工作尼乐清网站建设
  • 网站 语言切换怎么做信誉好的合肥网站推广
  • 深圳网站建设 网站设计网上银行
  • 优秀个人网站设计全免费的传奇手游
  • 贵州 网站备案wordpress登录不上去
  • 建一个区域网站需要多少资金中国建造师网官网登录入口
  • 高端品牌网站建设策略沂水做网站
  • 网站建设与设计的心得体会百度快速排名系统查询
  • 浙江省建设厅 网站是多少用自己的电脑做服务器弄网站
  • 昆明做企业网站哪家好一个网站的运营成本
  • 浙江网新股吧关键词优化的作用