jchitel / renlang

The Ren Programming Language
MIT License
4 stars 0 forks source link

Import/Export Additions #4

Closed jchitel closed 6 years ago

jchitel commented 6 years ago

Import/Export Additions

Description:

Exports are weird right now because they are sort of tacked on to declarations. They have their own scope for names, which sort of makes sense, but it can be done more intuitively. Also, as of now, exports are the only way to declare constants. It turned out that way because we wanted to be able to export expressions but had no way to declare non-exported expressions. We have an entire framework to support them, so we may as well just do it.

So these are the import forms we need to support:

  1. import from "module": ImportName: import default
  2. import from "module": { {name}, {name} as {alias}, ... }: import named
  3. import from "module": ImportName, { {name}, {name} as {alias}, ... }: import named and default
  4. import from "module": * as {namespace}: wildcard import
  5. import from "module": { {name}, {name} as {alias}, * as {namespace} }: import named and wildcard
  6. import from "module": ImportName, * as {namespace}: default and wildcard import
  7. import from "module": ImportName, { {name}, {name} as {alias}, * as {namespace} }: default, named and wildcard import

Currently 1 and 2 are already supported, and 3-7 are not yet supported.

And these are the export forms we need to support:

  1. export default {named declaration}: export default in place declaration
  2. export default {anon declaration}: export default anonymous declaration
  3. export default {name}: export default already declared declaration
  4. export {named declaration}: export declaration with declaration name
  5. export {name} = {named declaration}: export declaration with another name
  6. export {name} = {expression}: export constant under name
  7. export { {name}, {name} as {alias}, ... }: export already declared declaration(s)

Currently 1 and 3 are already supported, and 2 and 4 are not yet supported. 5 and 6 are currently supported and will be removed. 7 currently exists in a different form for single exports, it will be redone to support multiple exports.

And these are fusion import/export declarations (export forwarding):

  1. export from "module": ExportName: Default from another -> Named from yours
  2. export default from "module": Default from another -> Default from yours
  3. export default from "module": { {name} }: Named from another -> Default from yours
  4. export from "module:" { {name}, {name} as {alias}, ... }: Named from another -> Named from yours
  5. export default from "module": *: All from another -> Default from yours (grouped under a namespace object)
  6. export from "module": * as {name}: All from another -> Named from yours (grouped under a namepsace object)
  7. export from "module": *: All from another -> All from yours (ungrouped, just a 1:1 forward)

Currently none of these are supported.

With the above, all possible kinds of imports and exports should be supported.

New syntactic features:

New Tokens

CONST ::= "const"

New NonTerminals:

ConstantDeclaration ::= CONST IDENT EQUALS Expression
AnonDeclaration ::= AnonTypeDeclaration | AnonFunctionDeclaration | Expression
AnonTypeDeclaration ::= TYPE EQUALS Type
AnonFunctionDeclaration ::= FUNC Type TypeParamList? ParameterList FAT_ARROW (Expression | Block)
NamedExports ::= LBRACE (IDENT | IDENT AS IDENT) (+ sep COMMA) RBRACE
ExportForwards ::= ImportList
                 | MULTIPLY
DefaultExportForwards ::= LBRACE IDENT RBRACE
                        | MULTIPLY

Extended NonTerminals:

Program ::= ImportDeclaration* (Declaration | ExportDeclaration)*
Declaration ::= TypeDeclaration | FunctionDeclaration | ConstantDeclaration
ImportDeclaration ::= IMPORT FROM STRING_LITERAL COLON ImportList
ImportList ::= IDENT
              | NamedImports
              | IDENT COMMA NamedImports
              | MULTIPLY AS IDENT
              | IDENT COMMA MULTIPLY AS IDENT
NamedImports ::= LBRACE (IDENT | IDENT AS IDENT | MULTIPLY AS IDENT) (+ sep COMMA) RBRACE
ExportDeclaration ::= EXPORT DEFAULT (Declaration | AnonDeclaration | IDENT)
                    | EXPORT (Declaration | NamedExports)
                    | EXPORT FROM STRING_LITERAL COLON ExportForwards
                    | EXPORT DEFAULT FROM STRING_LITERAL (COLON DefaultExportForwards)?
Type ::= ... | Type DOT IDENT

New semantic features:

Transformation:

jchitel commented 6 years ago

Ok, the syntax (all parser-impl, CST, and AST logic) is done.

The remaining work:

Things to address:

jchitel commented 6 years ago

Additional problem:

This will actually be nice for several reasons:

jchitel commented 6 years ago

Ok, tests are done and all passing. We could probably use more coverage, but we're fine for the time being. Closing my first feature!