elipl/test/til/parse_atom_test.exs
Kacper Marzecki 748f87636a checkpoint
checkpoint

failing test

after fixing tests

checkpoint

checkpoint

checkpoint

re-work

asd

checkpoint

checkpoint

checkpoint

mix proj

checkpoint mix

first parser impl

checkpoint

fix tests

re-org parser

checkpoint strings

fix multiline strings

tuples

checkpoint maps

checkpoint

checkpoint

checkpoint

checkpoint

fix weird eof expression parse error

checkpoint before typing

checkpoint

checpoint

checkpoint

checkpoint

checkpoint ids in primitive types

checkpoint

checkpoint

fix tests

initial annotation

checkpoint

checkpoint

checkpoint

union subtyping

conventions

refactor - split typer

typing tuples

checkpoint test refactor

checkpoint test refactor

parsing atoms

checkpoint atoms

wip lists

checkpoint typing lists

checkopint

checkpoint

wip fixing

correct list typing

map discussion

checkpoint map basic typing

fix tests checkpoint

checkpoint

checkpoint

checkpoint

fix condition typing

fix literal keys in map types

checkpoint union types

checkpoint union type

checkpoint row types discussion & bidirectional typecheck

checkpoint

basic lambdas

checkpoint lambdas typing application

wip function application

checkpoint

checkpoint

checkpoint cduce

checkpoint

checkpoint

checkpoint

checkpoint

checkpoint

checkpoint

checkpoint
2025-06-13 23:48:07 +02:00

150 lines
5.5 KiB
Elixir

defmodule Til.ParseAtomTest do
use ExUnit.Case, async: true
alias Til.Parser
import Til.TestHelpers
describe "Atom parsing" do
test "parses a simple atom" do
source = ":hello"
{:ok, _nodes_map} = Parser.parse(source)
{atom_node, _map} = parse_and_get_first_node(source)
assert atom_node.ast_node_type == :literal_atom
assert atom_node.value == :hello
assert atom_node.raw_string == ":hello"
assert atom_node.location == [0, 1, 1, 6, 1, 7]
end
test "parses an atom with numbers and underscores" do
source = ":foo_123_bar"
{:ok, _nodes_map} = Parser.parse(source)
{atom_node, _map} = parse_and_get_first_node(source)
assert atom_node.ast_node_type == :literal_atom
assert atom_node.value == :foo_123_bar
assert atom_node.raw_string == ":foo_123_bar"
end
test "parses an atom within an s-expression" do
source = "(:an_atom)"
{:ok, nodes_map} = Parser.parse(source)
s_expr_node = get_first_child_node(nodes_map)
atom_node_id = hd(s_expr_node.children)
atom_node = get_node_by_id(nodes_map, atom_node_id)
assert atom_node.ast_node_type == :literal_atom
assert atom_node.value == :an_atom
assert atom_node.raw_string == ":an_atom"
# Location of :an_atom within ()
assert atom_node.location == [1, 1, 2, 9, 1, 10]
end
test "parses multiple atoms in an s-expression" do
source = "(:first :second)"
{:ok, nodes_map} = Parser.parse(source)
s_expr_node = get_first_child_node(nodes_map)
first_atom_node = get_node_by_id(nodes_map, Enum.at(s_expr_node.children, 0))
assert first_atom_node.ast_node_type == :literal_atom
assert first_atom_node.value == :first
assert first_atom_node.raw_string == ":first"
second_atom_node = get_node_by_id(nodes_map, Enum.at(s_expr_node.children, 1))
assert second_atom_node.ast_node_type == :literal_atom
assert second_atom_node.value == :second
assert second_atom_node.raw_string == ":second"
end
test "parses an atom followed immediately by an opening parenthesis (delimiter)" do
source = ":atom_name(foo)"
{:ok, nodes_map} = Parser.parse(source)
# First child of the file node should be the atom
atom_node = get_nth_child_node(nodes_map, 0)
assert atom_node.ast_node_type == :literal_atom
assert atom_node.value == :atom_name
assert atom_node.raw_string == ":atom_name"
assert atom_node.location == [0, 1, 1, 10, 1, 11]
# Second child should be the s-expression
s_expr_node = get_nth_child_node(nodes_map, 1)
assert s_expr_node.ast_node_type == :s_expression
assert s_expr_node.raw_string == "(foo)"
end
test "parses an atom at the end of input" do
source = " :last_atom "
{:ok, nodes_map} = Parser.parse(source)
# Use trimmed for helper
{atom_node, _map} = parse_and_get_first_node(String.trim(source))
assert atom_node.ast_node_type == :literal_atom
assert atom_node.value == :last_atom
assert atom_node.raw_string == ":last_atom"
# Location needs to be checked against the original source with whitespace
file_node = get_file_node_from_map(nodes_map)
actual_atom_node_id = hd(file_node.children)
actual_atom_node = get_node_by_id(nodes_map, actual_atom_node_id)
# " :last_atom "
assert actual_atom_node.location == [2, 1, 3, 12, 1, 13]
end
test "parses atom within a list expression" do
source = "[:my_list_atom]"
{:ok, nodes_map} = Parser.parse(source)
list_expr_node = get_first_child_node(nodes_map)
atom_node_id = hd(list_expr_node.children)
atom_node = get_node_by_id(nodes_map, atom_node_id)
assert atom_node.ast_node_type == :literal_atom
assert atom_node.value == :my_list_atom
assert atom_node.raw_string == ":my_list_atom"
end
test "parses atom within a tuple expression" do
source = "{:my_tuple_atom}"
{:ok, nodes_map} = Parser.parse(source)
tuple_expr_node = get_first_child_node(nodes_map)
atom_node_id = hd(tuple_expr_node.children)
atom_node = get_node_by_id(nodes_map, atom_node_id)
assert atom_node.ast_node_type == :literal_atom
assert atom_node.value == :my_tuple_atom
assert atom_node.raw_string == ":my_tuple_atom"
end
test "parses atom as a key in a map expression" do
source = "m{:key 1}"
{:ok, nodes_map} = Parser.parse(source)
map_expr_node = get_first_child_node(nodes_map)
key_node_id = Enum.at(map_expr_node.children, 0)
key_node = get_node_by_id(nodes_map, key_node_id)
assert key_node.ast_node_type == :literal_atom
assert key_node.value == :key
assert key_node.raw_string == ":key"
value_node_id = Enum.at(map_expr_node.children, 1)
value_node = get_node_by_id(nodes_map, value_node_id)
assert value_node.ast_node_type == :literal_integer
assert value_node.value == 1
end
test "parses atom as a value in a map expression" do
source = "m{'string_key' :atom_value}"
{:ok, nodes_map} = Parser.parse(source)
map_expr_node = get_first_child_node(nodes_map)
# string_key_node is child 0
value_node_id = Enum.at(map_expr_node.children, 1)
value_node = get_node_by_id(nodes_map, value_node_id)
assert value_node.ast_node_type == :literal_atom
assert value_node.value == :atom_value
assert value_node.raw_string == ":atom_value"
end
end
end