[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Dynamic loading progress
From: |
Stephen Leake |
Subject: |
Re: Dynamic loading progress |
Date: |
Mon, 16 Mar 2015 13:02:16 -0500 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/24.4 (windows-nt) |
Aurélien Aptel <address@hidden> writes:
> I've tried to implement modules using Daniel's plan. It turned out to
> be pretty easy, mostly because I'm more familiar with the Emacs
> codebase now and because it's a lot less intrusive than my previous
> attempt.
>
> It's not finished but I have a basic module working on linux. It's a
> proof of concept, basically.
I've implemented a test module that calls two Ada mode parser actions
(see below).
The real module will call the actual parser and build the action args
from the parse results.
I did not have to modify anything in the Emacs C code to make this work,
so it shows this module design is adquate for my use case so far.
I still need to implement the lexer level, which will either need to
call the current elisp lexer, or access the buffer text directly.
Any comments on the coding style? I don't think I need GCPRO on any of
the static emacs_values, because they are all declared at global level
in elisp.
--
-- Stephe
/*
Emacs module for Ada mode, providing a fast generalized LALR parser
*/
#include <emacs_module.h>
int plugin_is_GPL_compatible;
/* elisp functions */
static emacs_value aref;
static emacs_value cons;
static emacs_value length;
static emacs_value nil;
static emacs_value set;
static emacs_value symbol_value;
static emacs_value vector;
static emacs_value wisi_containing_action;
static emacs_value wisi_statement_action;
/* variables */
static emacs_value wisi_tokens;
/* array of symbols used in grammar actions */
static emacs_value* ada_grammar_names;
static emacs_value Fcons (emacs_env *env, emacs_value a, emacs_value b)
{
emacs_value args[] = { a, b };
return env->funcall (env, cons, 2, args);
}
/* Parse BUFFER, using parser in current module. */
static void parse (emacs_env *env, emacs_value buffer)
{
/* For now, just execute the actions from parsing second line in:
procedure Foo is
begin
A := 1;
end Foo;
ada_grammar.adb assignment_statement_0
wisi-tokens: [(name 24 . 25) (COLON_EQUAL 26 . 28) (expression 29 . 30)
(SEMICOLON 30 . 31)]
action: (wisi-statement-action [1 statement-start 2 statement-other 4
statement-end])
*/
/* Set `wisi-tokens'; wisi-tokens is let-bound in calling elisp
function. */
emacs_value tokens[] =
{ /* name "A" */
Fcons (env, ada_grammar_names[245], Fcons (env, env->make_fixnum (env,
24), env->make_fixnum (env, 25))),
/* COLON_EQUAL ":=" */
Fcons (env, ada_grammar_names[ 81], Fcons (env, env->make_fixnum (env,
26), env->make_fixnum (env, 28))),
/* expression "1" */
Fcons (env, ada_grammar_names[194], Fcons (env, env->make_fixnum (env,
29), env->make_fixnum (env, 30))),
/* SEMICOLON ";" */
Fcons (env, ada_grammar_names[ 95], Fcons (env, env->make_fixnum (env,
30), env->make_fixnum (env, 31)))
};
emacs_value args_1[] = { wisi_tokens, env->funcall (env, vector, 4, tokens) };
env->funcall (env, set, 2, args_1);
emacs_value pairs[] =
{ env->make_fixnum (env, 1), ada_grammar_names[341], /* statement-start */
env->make_fixnum (env, 2), ada_grammar_names[342], /* statement-other */
env->make_fixnum (env, 4), ada_grammar_names[343] /* statement-end */
};
emacs_value args_2[] = { env->funcall (env, vector, 6, pairs) };
env->funcall (env, wisi_statement_action, 1, args_2);
emacs_value args_3[] = { env->make_fixnum (env, 2), env->make_fixnum (env, 3)
};
env->funcall (env, wisi_containing_action, 2, args_3);
}
/* elisp-callable wrapper for `parse'
args: BUFFER
*/
static emacs_value Fparse (emacs_env *env, int nargs, emacs_value args[])
{
parse (env, args[0]);
return nil;
}
/* Binds NAME to FUN */
static void bind_function (emacs_env *env, const char *name, emacs_value Ffun)
{
emacs_value Qfset = env->intern (env, "fset");
emacs_value Qsym = env->intern (env, name);
emacs_value args[] = { Qsym, Ffun };
env->funcall (env, Qfset, 2, args);
}
/* standard Emacs module init */
int emacs_module_init (struct emacs_runtime *ert)
{
emacs_env *env = ert->get_environment (ert);
aref = env->intern (env, "aref");
cons = env->intern (env, "cons");
length = env->intern (env, "length");
nil = env->intern (env, "nil");
set = env->intern (env, "set");
symbol_value = env->intern (env, "symbol-value");
vector = env->intern (env, "vector");
wisi_statement_action = env->intern (env, "wisi-statement-action");
wisi_containing_action = env->intern (env, "wisi-containing-action");
wisi_tokens = env->intern (env, "wisi-tokens");
emacs_value names_1 = env->intern (env, "ada_grammar-names");
emacs_value args_1[] = { names_1 };
emacs_value names_2 = env->funcall (env, symbol_value, 1, args_1);
emacs_value args_2[] = { names_2 };
int64_t names_length = env->fixnum_to_int (env, env->funcall (env, length, 1,
args_2));
ada_grammar_names = malloc (names_length * sizeof (int64_t));
for (int i = 0; i < names_length; i++)
{
emacs_value args[] = {names_2, env->make_fixnum (env, i)};
ada_grammar_names[i] = env->funcall (env, aref, 2, args);
};
bind_function (env, "wisi-module-parse", env->make_function (env, 1, 1,
Fparse));
return 0;
}
- Re: Dynamic loading progress, (continued)
- Re: Dynamic loading progress, Aurélien Aptel, 2015/03/05
- Re: Dynamic loading progress, Aurélien Aptel, 2015/03/05
- Re: Dynamic loading progress, Stefan Monnier, 2015/03/06
- Re: Dynamic loading progress, Daniel Colascione, 2015/03/06
- Re: Dynamic loading progress, Stefan Monnier, 2015/03/09
Re: Dynamic loading progress, Stephen Leake, 2015/03/05
Re: Dynamic loading progress, Stephen Leake, 2015/03/05
Re: Dynamic loading progress,
Stephen Leake <=
Re: Dynamic loading progress, Stephen Leake, 2015/03/17
Re: Dynamic loading progress, Stephen Leake, 2015/03/24