Helper API

The helper library contains the following kinds of functions:

  • an unwrap() function that returns the primitive representation of a syntax object
  • is* functions that test the type of a syntax object (e.g. isIdentifier() for identifiers and isStringLiteral() for strings)
  • from* functions that create new syntax objects from primitive data

unwrap

unwrap(value : any)
Arguments:
  • value (any) – The value to unwrap, can be anything.
Return type:

{ value?: string | number | Term[] }

When invoked with a flat syntax object (i.e. not delimiters), unwrap() returns an object with a single value property that holds the primitive representation of that piece of syntax (a string for string literals, keywords, and identifiers or a number for numeric literals).

For syntax objects that represent delimiters, unwrap() returns an object who’s value property is a list of the syntax objects inside the delimiter.

For all other inputs unwrap() returns the empty object.

import { unwrap } from '@sweet-js/helpers' for syntax;

syntax m = ctx => {
  let id = ctx.next().value;
  let delim = ctx.next().value;

  unwrap(id).value === 'foo';  // true
  let num = unwrap(delim).value.get(1);
  unwrap(num).value === 1;     // true
  // ...
};
m foo (1)

is*

isIdentifier(value : any)

Returns true if the argument is an identifier.

Arguments:
  • value (any) – The value to check.
Return type:

boolean

isNumericLiteral(value : any)

Returns true if the argument is a numeric literal.

Arguments:
  • value (any) – The value to check.
Return type:

boolean

isStringLiteral(value : any)

Returns true if the argument is a string literal.

Arguments:
  • value (any) – The value to check.
Return type:

boolean

isKeyword(value : any)

Returns true if the argument is a keyword.

Arguments:
  • value (any) – The value to check.
Return type:

boolean

isPunctuator(value : any)

Returns true if the argument is a punctuator (e.g. ., ;, *, etc.).

Arguments:
  • value (any) – The value to check.
Return type:

boolean

isTemplate(value : any)

Returns true if the argument is a template.

Arguments:
  • value (any) – The value to check.
Return type:

boolean

isSyntaxTemplate(value : any)

Returns true if the argument is a syntax template.

Arguments:
  • value (any) – The value to check.
Return type:

boolean

isDelimiter(value : any)

Returns true if the argument is a delimiter (e.g. (), [], {}).

Arguments:
  • value (any) – The value to check.
Return type:

boolean

isParens(value : any)

Returns true if the argument is a paren delimiter (e.g. ()).

Arguments:
  • value (any) – The value to check.
Return type:

boolean

isBrackets(value : any)

Returns true if the argument is a brackets delimiter (e.g. []).

Arguments:
  • value (any) – The value to check.
Return type:

boolean

isBraces(value : any)

Returns true if the argument is a braces delimiter (e.g. {}).

Arguments:
  • value (any) – The value to check.
Return type:

boolean

from*

fromIdentifier(other : Term, s : string)

Create a new identifier syntax object named after the provided string using the lexical context from other.

Arguments:
  • other (Term) – The term to take the lexical context from.
  • s (string) – The name of the new identifier
Return type:

Term

import { fromIdentifier } from '@sweet-js/helpers' for syntax;

syntax m = ctx => {
  let dummy = #`dummy`.get(0);

  return #`${fromIdentifier(dummy, 'bar')}`;
};
m foo
bar

Be careful which syntax object you use to create a new syntax object via fromIdentifier and related functions since the new object will share the original’s lexical context. In most cases you will want to create a “dummy” syntax object inside a macro definition and then use that as a base to create new objects. By using a dummy syntax object you are using the scope of the macro definition; usually the macro definition scope is what you want.

You may be tempted to reuse the syntax object provided by ctx.name() but resist that feeling! The ctx.name() syntax object comes from the macro call-site and so any syntax objects created from it will carry the lexical context of the call-site. Sometimes this is what you want, but most of the time this breaks hygiene.

fromNumber(other : Syntax, n : number)

Create a new numeric literal syntax object with the value n using the lexical context from other.

Arguments:
  • other (Term) – The term to take the lexical context from.
  • n (number) – The numeric value of the new numeric literal
Return type:

Term

import { fromNumber } from '@sweet-js/helpers' for syntax;

syntax m = ctx => {
  let dummy = #`dummy`.get(0);

  return #`${fromNumber(dummy, 1)}`;
};
m
1
fromStringLiteral(other : Syntax, s : string)

Create a new string literal syntax object with the value s using the lexical context from other.

Arguments:
  • other (Term) – The term to take the lexical context from.
  • s (number) – The string value of the new string literal
Return type:

Term

import { unwrap, fromStringLiteral } from '@sweet-js/helpers' for syntax;

syntax to_str = ctx => {
  let dummy = #`dummy`.get(0);
  let arg = unwrap(ctx.next().value).value;
  return #`${fromStringLiteral(dummy, arg)}`;
}
to_str foo
'foo'
fromPunctuator(other : Syntax, punc : string)

Creates a punctuator (e.g. +, ==, etc.) from its string representation punc using the lexical context from other.

Arguments:
  • other (Term) – The term to take the lexical context from.
  • punc (number) – The string representation of the new punctuator.
Return type:

Term

import { fromPunctuator } from '@sweet-js/helpers' for syntax;

syntax m = ctx => {
  let dummy = #`dummy`.get(0);
  return #`1 ${fromPunctuator(dummy, '+')} 1`;
};
m
1 + 1
fromKeyword(other : Syntax, kwd : string)

Create a new keyword syntax object with the value kwd using the lexical context from other.

Arguments:
  • other (Term) – The term to take the lexical context from.
  • kwd (number) – The string representation of the new keyword.
Return type:

Term

syntax m = ctx => {
  let dummy = #`dummy`.get(0);
  return #`${fromKeyword(dummy, 'let')} x = 1`;
};
m
let x = 1
fromBraces(other : Syntax, inner : Term[])

Creates a curly brace delimiter with inner syntax objects inner using the lexical context from other.

Arguments:
  • other (Term) – The term to take the lexical context from.
  • inner (Term []) – The list terms to go inside the delimiter.
Return type:

Term

import { fromBraces } from '@sweet-js/helpers' for syntax;

syntax m = ctx => {
  let dummy = #`dummy`.get(0);
  let block = #`let x = 1;`;
  return #`${fromBraces(dummy, block)}`;
};
m
{
  let x = 1;
}
fromBrackets(other : Syntax, inner : Term[])

Creates a bracket delimiter with inner syntax objects inner using the lexical context from other.

Arguments:
  • other (Term) – The term to take the lexical context from.
  • inner (Term []) – The list terms to go inside the delimiter.
Return type:

Term

syntax m = ctx => {
  let dummy = #`dummy`.get(0);
  let elements = #`1, 2, 3`;
  return #`${fromBrackets(dummy, elements)}`;
};
m
[1, 2, 3]
fromParens(other : Syntax, inner : Term[])

Creates a paren delimiter with inner syntax objects inner using the lexical context from other.

Arguments:
  • other (Term) – The term to take the lexical context from.
  • inner (Term []) – The list terms to go inside the delimiter.
Return type:

Term

import { fromParens } from '@sweet-js/helpers' for syntax;

syntax m = ctx => {
  let dummy = #`dummy`.get(0);
  let expr = #`5 * 5`;
  return #`1 + ${fromParens(dummy, expr)}`;
};
m
1 + (5 * 5)