Skip to content

Conversation

@igrvlhlb
Copy link
Contributor

@igrvlhlb igrvlhlb commented Dec 2, 2025

This pull request introduces support for Pallene type declaration files (.d.pln), allowing the compiler to parse and verify/typecheck type files in addition to regular Pallene source files. The changes include updates to the parser, typechecker, driver, CLI, and utility functions to handle the new file format, as well as new tests to verify correct parsing and type checking of type declaration files.

Type Declaration File Support

  • Added a new AST union TypeFile in src/pallene/ast.lua to represent type declaration files and their components (Typealias, Record, Decl).
  • Implemented parsing logic for .d.pln files in src/pallene/parser.lua, including the TypeDeclarationFile parser method and extension-based dispatch in the main parse function. [1] [2]
  • Extended the typechecker to handle type declaration file ASTs, adding the check_type_file method in src/pallene/typechecker.lua. [1] [2]

Compiler and CLI Integration (Extra)

  • Added a new CLI flag --emit-types to src/pallene/pallenec.lua, enabling users to generate .d.pln files, and integrated it into the main command dispatch. [1] [2]

Utilities and Testing

  • Introduced utility functions in src/pallene/util.lua to correctly split and recognize multi-part extensions like .d.pln, supporting robust file name handling.
  • Added tests for parsing and type checking type declaration files in spec/parser_spec.lua.

@igrvlhlb igrvlhlb force-pushed the parse-pallene-types-file branch from 7868a52 to c04903a Compare December 2, 2025 22:20
else
self:unexpected_token_error("a type declaration")
end
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we encounter an invalid token, the while loop will exit and this function will return as if there was not a problem.

  1. I think the while should be "while not end-of-file"
  2. Please create test cases for the "expected a type declaration" errors

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the while should be "while not end-of-file"

Should we still throw an error if we don't find at least one declaration? If so, we can go with a repeat-until

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should allow empty files, in case the module exports nothing. (Also test that...)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to write the error test in a assert_program_error() fashion, but I couldn't get it to work. So I wrote it another way (src/spec/parser_spec.lua:979-990)

local type_checker = Typechecker.new()
if prog_ast._tag == "ast.Program.Program" then
return type_checker:check_program(prog_ast)
elseif prog_ast._tag == "ast.TypeFile.Decls" then
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This kind of if-else-if doesn't feel right. The type (ast.Program) should be the same in all branches.

I suspect that you actually want to have separate type checking functions instead of a catch-all typechecker.check

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same goes to Parser.parse()? Or is it ok for that case?

If I understand it correctly, you are suggesting that we have a new function in the typechecker and the responsibility to choose which one to call must be in driver.compile_internal(). Right?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes.

return base_name, parts[#parts]
end
end

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if it would be simpler to not split the string. We can could the string itself to see if it ends in ".pln" or ".d.pln".

Copy link
Contributor Author

@igrvlhlb igrvlhlb Dec 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right. Also now I see that logic is not necessary, as "." is not an allowed character in file names.

So what I plan to do is this:

  • get rid of that new function util.split_pallene_ext() (and split_all_ext)
  • keep using util.split_ext with the following modification
 function util.split_ext(file_name)
-    local name, ext = string.match(file_name, "(.*)%.(.*)")
+    local name, ext = string.match(file_name, "(.-)%.(.*)")
     return name, ext
 end

That way string.match() will match name only until the first '.', and ext will be the rest of the string. Is that ok?

* Fix logic in `split_ext` and remove unnecessary new functions;
* Fix `.d.pln` parsing loop that could stop before file end;
* Create a new function for `.d.pln` typechecking.
* Add tests
@igrvlhlb igrvlhlb force-pushed the parse-pallene-types-file branch from 764279d to e31345a Compare December 3, 2025 13:50
@igrvlhlb igrvlhlb requested a review from hugomg December 3, 2025 14:05
Copy link
Member

@hugomg hugomg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Acho que precisamos de funções separadas para o compile_internal e o parser.parse.

Pense em qual seria o tipo de parser.parse. Hoje é uma função que as vezes retorna um ast.Program e as vezes retorna um ast.TypeFile. Isso até dá pra escrever em Lua, que é uma linguagem dinâmica, mas não funcionaria se quisessemos converter esse código para Pallene no futuro.

Um problema semelhante acontece na compile_internal, que hoje está com um if que verifica a extensão e retorna tipos de dados diferentes dependendo do valor da extensão.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants