This should go in the docs .. How to do literals ==============
Step 1. Define the lexicology. +++++++++++++++++++++++ You will typically make a file like lib/grammar/grammar_float_lexer.flxh shown below. Don't forget to add this to the syntax file list lib/grammar/grammar.files so it is included. You may also open the syntax in two steps: first add the dssl (Domain Specific Sublanguage) name to the requirements for felix in: lib/grammar/grammar_lexer.flxh which includes: syntax lexer { requires global_regdefs; requires felix_ident_lexer; requires felix_ident_lexer; requires felix_int_lexer; requires felix_float_lexer; requires felix_string_lexer; } which it present is a security check, and also ensures your grammar is opened (because it's required by felix in lib/grammar/felix.flxh, and opened in lib/grammar/save.flxh which is the file that actually builds the automaton). Your definition for floating literals is like this: // lib/grammar/grammar_float_lexer.flxh syntax felix_float_lexer { // provide some regular definition helpers regdef decimal_string = digit (underscore? digit) *; regdef hexadecimal_string = hexdigit (underscore? hexdigit) *; regdef decimal_fractional_constant = decimal_string '.' decimal_string; regdef hexadecimal_fractional_constant = ("0x" |"0X") hexadecimal_string '.' hexadecimal_string; regdef decimal_exponent = ('E'|'e') ('+'|'-')? decimal_string; regdef binary_exponent = ('P'|'p') ('+'|'-')? decimal_string; regdef floating_suffix = 'L' | 'l' | 'F' | 'f' | 'D' | 'd'; // here's the final definition for floats regdef floating_literal = ( decimal_fractional_constant decimal_exponent? | hexadecimal_fractional_constant binary_exponent? ) floating_suffix?; // Now a nice shorthand regdef sfloat = floating_literal; // Now, use the literal keyword to lift the regular // expression "sfloat" into the grammar, that is, // make it a non-terminal // The Scheme action code makes a tripe // // ( felix-type value C-encoding) // // which it does by examining the lexeme literal sfloat =># """ (let* ( (val (stripus _1)) (val (tolower-string val)) (n (string-length val)) (n-1 (- n 1)) (ch (substring val n-1 n)) (rest (substring val 0 n-1)) (result (if (equal? ch "l") `("ldouble" ,val ,val) (if (equal? ch "f") `("float" ,val ,val) `("double" ,val ,val)) ) ) ) result ) """; // Now all we have to do is convert the literal value // into an actual AST value of literal type // and tell the parser the non-terminal sfloat // is a sliteral with a new production for sliteral sliteral := sfloat =># "`(ast_literal ,_sr ,@_1)"; // if you check the grammar for expressions you'll // fine sliteral's are already counted as expressions // so we just added a new kind of expression } Step 2: Define the type ++++++++++++++++++ We now have to define the types we introduced in the **top level** of some library file. For the floats this has been done in lib/plat/ctypedefs.flx: pod type float = "float"; pod type double = "double"; pod type ldouble = "long double"; Note this is a generated file (so don't look in src/lib/ for it, look in build/release/lib/plat instead). Of course, one has to also define operations on these types .. but you already know now to do that in Felix! So now you can write var x = 0.2f; // float literal and the ability to write 0.2f as part of the Felix language is now entirely defined in the library. The compiler knows nothing about it. -- john skaller skal...@users.sourceforge.net http://felix-lang.org ------------------------------------------------------------------------------ Better than sec? Nothing is better than sec when it comes to monitoring Big Data applications. Try Boundary one-second resolution app monitoring today. Free. http://p.sf.net/sfu/Boundary-dev2dev _______________________________________________ Felix-language mailing list Felix-language@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/felix-language