Skip to content

Commit

Permalink
Add support for interfacing with C libraries
Browse files Browse the repository at this point in the history
This adds support for linking against C libraries and using their types
and functions. The FFI is fairly strict and a bit limited, such as not
performing automatic type conversions, but this is a deliberate choice:
it keeps the compiler's complexity at a reasonable level, and it should
(hopefully) further drive home the idea that one should avoid
interfacing with C as much as they can, as all of Inko's safety
guarantees are thrown out of the window when doing so.

As part of this work, the precedence of type casts (`x as Type`) is
changed to be the same as binary operators. This means expressions such
as `x as Foo + y` are now valid, instead of resulting in a syntax error.
This makes working with type casts (something you'll need to use more
often when working with C code) less painful.

This fixes #290.

Changelog: added
  • Loading branch information
yorickpeterse committed Jul 2, 2023
1 parent 59578a1 commit 3a117c6
Show file tree
Hide file tree
Showing 59 changed files with 3,233 additions and 2,659 deletions.
5 changes: 5 additions & 0 deletions ast/src/lexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ pub enum TokenKind {
UnsignedShrAssign,
While,
Whitespace,
Extern,
}

impl TokenKind {
Expand Down Expand Up @@ -274,6 +275,7 @@ impl TokenKind {
TokenKind::Recover => "the 'recover' keyword",
TokenKind::Nil => "the 'nil' keyword",
TokenKind::Replace => "a '=:'",
TokenKind::Extern => "the 'extern' keyword",
}
}
}
Expand Down Expand Up @@ -340,6 +342,7 @@ impl Token {
| TokenKind::False
| TokenKind::Case
| TokenKind::Enum
| TokenKind::Extern
)
}

Expand Down Expand Up @@ -995,6 +998,7 @@ impl Lexer {
"import" => TokenKind::Import,
"return" => TokenKind::Return,
"static" => TokenKind::Static,
"extern" => TokenKind::Extern,
_ => TokenKind::Identifier,
},
7 => match value.as_str() {
Expand Down Expand Up @@ -2073,6 +2077,7 @@ mod tests {
assert_token!("import", Import, "import", 1..=1, 1..=6);
assert_token!("return", Return, "return", 1..=1, 1..=6);
assert_token!("static", Static, "static", 1..=1, 1..=6);
assert_token!("extern", Extern, "extern", 1..=1, 1..=6);

assert_token!("builtin", Builtin, "builtin", 1..=1, 1..=7);
assert_token!("recover", Recover, "recover", 1..=1, 1..=7);
Expand Down
22 changes: 22 additions & 0 deletions ast/src/nodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,24 @@ impl Node for Import {
}
}

#[derive(Debug, PartialEq, Eq)]
pub struct ExternImportPath {
pub path: String,
pub location: SourceLocation,
}

#[derive(Debug, PartialEq, Eq)]
pub struct ExternImport {
pub path: ExternImportPath,
pub location: SourceLocation,
}

impl Node for ExternImport {
fn location(&self) -> &SourceLocation {
&self.location
}
}

#[derive(Debug, PartialEq, Eq)]
pub struct DefineConstant {
pub public: bool,
Expand All @@ -359,6 +377,7 @@ pub enum MethodKind {
Moving,
Mutable,
AsyncMutable,
Extern,
}

#[derive(Debug, PartialEq, Eq)]
Expand Down Expand Up @@ -419,6 +438,7 @@ pub enum ClassKind {
Builtin,
Enum,
Regular,
Extern,
}

#[derive(Debug, PartialEq, Eq)]
Expand Down Expand Up @@ -501,6 +521,7 @@ pub enum TopLevelExpression {
ReopenClass(Box<ReopenClass>),
ImplementTrait(Box<ImplementTrait>),
Import(Box<Import>),
ExternImport(Box<ExternImport>),
}

impl Node for TopLevelExpression {
Expand All @@ -513,6 +534,7 @@ impl Node for TopLevelExpression {
TopLevelExpression::ReopenClass(ref typ) => typ.location(),
TopLevelExpression::ImplementTrait(ref typ) => typ.location(),
TopLevelExpression::Import(ref typ) => typ.location(),
TopLevelExpression::ExternImport(ref typ) => typ.location(),
}
}
}
Expand Down
Loading

0 comments on commit 3a117c6

Please sign in to comment.