Syntax parameters allow us to play around with hygiene in a principled fashion.
stxParam it = function() { throw new Error("must be rebound"); };
let aif = macro {
    rule { ($cond ...) { $body ...} } => {
	var it_inner  = $cond ...;
	if (it_inner) {
	    syntaxParameterize it (it_inner) {
		$body ...
	    }
	}
    }
}Not super happy about the syntax. In particular the Racket form is
more general letting syntaxParameterize take syntax-rules as a way
of matching more than just the identifier. Perhaps we only need to
start with this simplified version? The more general syntax gets ugly
really quick:
stxParam it = function() { throw new Error("must be rebound"); };
let aif = macro {
    rule { ($cond ...) { $body ...} } => {
	var it_inner  = $cond ...;
	if (it_inner) {
	    syntaxParameterize it {
		rule { } => { it_inner }
	    } {
		$body ...
	    }
	}
    }
}Or something like that. Ugh!
We'll need to implement a few functions the build out syntax parameters.
define-syntax in racket load an expression in the compiletime
environment and binds the name in the current scope. Basically it's
like let but for compiletime values.
The define prefix doesn't make sense for JS. Perhaps just syntax?
This would just stick a function into the transformer environment:
syntax name = function(x) {
    return x + 1;
}This can also be used to define macros of course:
syntax id = macro {
    rule { $x } => { $x }
}Or just arbitrary values:
syntax compiletimeNumber = 42;This if course slightly conflicts with the existing syntax {}
template but we can fix that up.
Alternately we could use stx:
stx name = function(x) { return x };
stx id = macro {
    rule { $x } => { $x }
}
stx compiletimeNumber = 42;The nice things about this is it's the same number of characters as
var and let though maybe it is too terse (where have all the
vowels gone?).
Recursive bindings in macros could be handled like so:
stx rec = macro rec {
    // ...
}The nice thing here is that the default is not to bind inside of the macros. Usually what you want.
To implement this you'll need to add a form the TermTree hierarchy
and handle recognizing this in enforest. Something like:
function enforest() {
    //...
    if (head === "stx" &&
	rest[0] === ident &&
	rest[1] === "=" &&
	rest[2] === expr) {
	StxDef.create(head, rest[0], rest[1], rest[2]);
	// ...
    }
    //...
}Then in expandTermTree you'll want to load any StxDef term trees
into the compiletime environment (e.g. context.env) and bind the
name appropriately. Basically do something similar to what
expandTermTree does for let-bound macros currently.
syntax-local-value in racket retrieves a value from the compiletime
environment.
For JS how about we call this function syntaxLocalValue()? Was
worried before that this is too long but I think it works. It is used
like this:
stx id = function(x) { return x };
stx m = macro {
    case { () } => {
	var stxId = syntaxLocalValue(#{id});
	letstx $x = [makeValue(stxId(42), #{here})];
	return #{$x}
    }
}
m();
// expands to:
// 42;Should actually be pretty straightforward. Just add a function to the
object in loadMacroDef called syntaxLocalValue that takes a syntax
object (or a one element array for convenience since #{id} returns
an array of one syntax object) and the retrieves the value stored in
context.env with that syntax object (call getMacroInEnv etc.).
The racket function syntax-local-get-shadower returns the nearest
shadowing identifier syntax object or the given syntax object if
nothing is shadowing in the context of expansion.
In JS we can just camelCase the same name I think:
var foo = 42;
stx m = macro {
    case {_ () } => {
	letstx $id = [syntaxLocalGetShadower(#{foo})];
	return #{$id}
    }
}
function f(foo) {
    m ();
    // expands to:
    // foo         <- the `foo` bound to the function parameter, not 42
}I think the way to make this work you need to get access to the
expansion context and then create a syntax object with the .value of
the syntax object passed to syntaxLocalGetShadower but with the
lexical context of the expansion context. How can we reify the
expansion context?
Might need this, not sure.
Adds the mark of the current expansion context to a syntax object.
Actually, we might not need this function to implement syntax parameters so ignore it for now.
The racket function make-rename-transformer is sort of like a macro
that just swaps around names.
For JS I think we can just call it makeRenameTransformer.
stxParm is just a macro that expands to two syntax definitions:
stxParm name = function() { throw "must rebind"; };Expands to:
stx name_internal = function() { throw "must rebind"; };
stx name = function(stx, context, prevStx, prevTerms) {
    var shadower = syntaxLocalGetShadower(#{name_internal});
    var shadowerValue = syntaxLocalValue(shadower);
    return shadowerValue(stx, context, prevStx, prevTerms);
}syntaxParameterize is just a macro that expands to something like:
stxParm name = function() { throw "must rebind"; };
var myName = "foo";
syntaxParameterize name { rule { } => { myName }} {
    name;
}goes to:
stxParm name = function() { throw "must rebind"; };
var myName = "foo";
stx name = macro { rule {} => { myName }}
name;Or maybe we don't even need syntaxParameterize? All that's really
necessary is redefining what name expands to.
Hello,
I got the implementation of the first part, defining the primitive part and store it in the env context.
Implementation part,
defined the syntax parameter as

Next I would be working onFew question:
thanks
Vimal