Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Self hosted parser completion #873

Merged
merged 55 commits into from Apr 11, 2018
Merged

Self hosted parser completion #873

merged 55 commits into from Apr 11, 2018

Conversation

Hejsil
Copy link
Sponsor Contributor

@Hejsil Hejsil commented Mar 30, 2018

This is in no way done, but I thought, that instead of just pushing my work on the self-hosted parser to master, I would make this PR. This allows me to write a lot of tests that fail, and slowly work towards getting them all passing.

Checklist!

  • extern "c" fn puts(s: &const u8) c_int;
  • Muti line strings
  • Indexing
  • Slicing
  • Types
    • Array
    • Slice
    • Function
    • error
  • Literals
    • Boolean
    • Char
    • null
  • unreachable
  • this
  • Operator precedence and expression grouping (parentheses)
  • Struct declaration
  • Enum declaration
  • Union declaration
  • Error set declaration
  • Container initializers
  • Labeled blocks
  • switch
  • while
  • for
  • if
  • defer
  • catch
  • comptime
  • Inline assembly
  • Coroutines
  • use
  • Parse std

When all these are checked and the self-hosted parser can parse the entire std library and all tests, then it's ready for a merge.

@andrewrk
Copy link
Member

Great work so far. It's been really exciting to watch your progress


try testCanonical(
\\test "test array" {
\\ const a : [2]u8 = [2]u8{ 1, 2 };
Copy link
Member

Choose a reason for hiding this comment

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

I think canonical var decl is:
const name: type = value;
(No space between colon and var name)

);

try testCanonical(
\\test "percendence" {
Copy link
Contributor

Choose a reason for hiding this comment

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

'precedence' typo?

@Hejsil
Copy link
Sponsor Contributor Author

Hejsil commented Mar 31, 2018

I've now added test cases for what I hope is all of Zig's syntax. I've also added a checklist with all everything that is missing from the self-hosted parser.

\\ x += 1;
\\ suspend |p| {
\\ }
\\ const p = async simpleAsyncFn() cache unreachable;
Copy link
Member

Choose a reason for hiding this comment

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

I hate it when the cache is unreachable :)

Copy link
Sponsor Contributor Author

Choose a reason for hiding this comment

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

Lol, yes :)

@Hejsil
Copy link
Sponsor Contributor Author

Hejsil commented Apr 3, 2018

@andrewrk The variable declaration syntax in the self-hosted parser is currently not being parsed correctly. var a: u8 = 1; is parsed intovar a: ( u8 = 1 ) ;.

In the C++ compiler, this is solved by parsing type expressions as prefix operators first and therefore requiring parentheses for infix operators to be used in type expressions. This solution cannot be used in the self-hosted parser because of the way expressions are parsed.

Do we rewrite expression parsing to make this work or disallow assignment as an expression?

@Hejsil
Copy link
Sponsor Contributor Author

Hejsil commented Apr 3, 2018

There is also the option of checking if the type expression is an assignment and then transform var a: (u8 = 0); -> var a: u8 = 0;. The only problem with this solution is, that we are using an arena as an allocator, so we cannot free the NodeInfixOp node.

@Hejsil
Copy link
Sponsor Contributor Author

Hejsil commented Apr 3, 2018

Also, in the C++ compiler, this is allowed:

var a: u8 = 0;
const b = a = 2;

I don't think this has any use. @typeOf(b) == void, and I don't think that is what a person intended if they wrote this piece of code.

@Hejsil
Copy link
Sponsor Contributor Author

Hejsil commented Apr 3, 2018

This is also a problem when implementing initializers :/

fn main() void {}

Gets parsed as:

fn main() (void {})

* I also moved some tests down, as they fail in ways I can't fix yet
* Now, the arraylist from the root node is passed through the states.
* This allows us to reuse the code for enums, unions and structs
@andrewrk
Copy link
Member

andrewrk commented Apr 3, 2018

I think assignments should not be expressions.

@Hejsil
Copy link
Sponsor Contributor Author

Hejsil commented Apr 3, 2018

Alright. Then we just need to solve #760 :)

@andrewrk
Copy link
Member

From the appveyor build:
lld: error: undefined symbol: memmove

Wow, I've not seen this happen yet. I guess we need to add a memmove implementation to std/special/builtin.zig.

@andrewrk andrewrk merged commit 64d96ad into master Apr 11, 2018
@andrewrk andrewrk deleted the self-hosted-parser branch April 11, 2018 02:47
@andrewrk
Copy link
Member

andrewrk commented Apr 11, 2018

All tests passing, merged!

Let's open new issues for whatever's left.

@tiehuis
Copy link
Member

tiehuis commented Apr 11, 2018

Great work, @Hejsil.

@Hejsil Hejsil mentioned this pull request Apr 11, 2018
14 tasks
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.

None yet

5 participants