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

Import statement #27

Closed
KCreate opened this issue Jan 24, 2018 · 7 comments
Closed

Import statement #27

KCreate opened this issue Jan 24, 2018 · 7 comments

Comments

@KCreate
Copy link
Owner

KCreate commented Jan 24, 2018

Description

import statements are used to include libraries and other charly source files.

Import

  • following the import keyword with an identifier will import that identifier
// source
import foo

// desugared
const foo = __import("foo", "/tmp/1234")

Import from expression

  • if the library name is anything other than an identifier it will be treated as an expression
    • this can be used to dynamically import files
  • the expression may be wrapped in parens
    • note: parens cannot be used to form a tuple-like syntax
// source
import "myfile.ch"
import (foo) as foolib
import getlibname() as lib

// desugared
__import("myfile.ch", "/tmp/1234") // no declarations generated
const foolib = __import(foo, "/tmp/1234")
const lib = __import(getlibname(), "/tmp/1234")

Renamed import

  • the as keyword can be used to assign the imported library to a different name
// source
import foo as myfoo
import "bar" as mybar

// desugared
const foo = __import("foo", "/tmp/1234")
const myfoo = foo
const mybar = __import("bar", "/tmp/1234")

Import specific fields

  • curly braces can be used to extract specific fields from a library
  • imported fields can be renamed via an as keyword
    • both declarations should be accessable
  • the library name needs to be passed after a from keyword
  • this syntax can be combined with the as syntax
// source
import { open, read, close } from fs
import { open, read, close } from fs as thefslib
import { foo as f, bar as b } from foobarlib

// desugared
const fs = __import("fs", "/tmp/1234")
const { open, read, close } = fs

const fs = __import("fs", "/tmp/1234")
const thefslib = fs
const { open, read, close } = fs

const foobarlib = __import("foobarlib", "/tmp/1234")
const { foo, bar } = foobarlib
const f = foo
const b = bar

Module resolution

  • Runtime has table of known builtin modules
    • Can return those directly without any filesystem lookups
  • Absolute paths (paths starting with a /)
    • Path is looked up directly
    • No further lookups are done
  • All other paths are looked up in the folder hierarchy of the file where the import occured

The import statement import "somelib" in the file /foo/bar/baz/index.ch would result in the following filesystem lookups:

  • /foo/bar/baz/somelib
  • /foo/bar/baz/somelib.ch
  • /foo/bar/somelib
  • /foo/bar/somelib.ch
  • /foo/somelib
  • /foo/somelib.ch
  • /somelib
  • /somelib.ch

Module caching

  • When a module is executed, a reference to it is stored in a cache somewhere
  • If in the future the same module gets included again, the cached version is returned
    • The cache stores the mtime of the source file
    • If the file was modified after it was put into the cache, the cache entry is cleared and the module is executed again
  • If two fibers import the same module, only a single instance of the module should be created
    • Only a single module should be executed
    • Fibers need to acquire some kind of lock on the import path
@KCreate
Copy link
Owner Author

KCreate commented Jul 7, 2019

Implement a way to store compiled files so the VM doesn't have to recompile a file every time it's included.

Or alternatively, should this be allowed? So you always get a fresh version of the file. The only problem with that would be weird interactions between different versions of the file. Developers would have to account for that themselves though.

@tekknolagi
Copy link
Collaborator

You can do what CPython does with __pycache__, etc

@KCreate
Copy link
Owner Author

KCreate commented Jul 8, 2019

@tekknolagi Ah I see, and then if people want to use the newest version they can just delete the file?

@tekknolagi
Copy link
Collaborator

No, it should either compare mtime or compare hashes so that it can automatically detect when it needs to recompile

@KCreate
Copy link
Owner Author

KCreate commented Jul 9, 2019

I see, so I figure these pyc files contain everything needed to go and don't depend on the CPython VM to keep around some information? A CPython VM could just execute the whole thing if it stumbles upon some pyc files?

@tekknolagi
Copy link
Collaborator

In CPython they contain a marshalled code object plus some magic number and metadata. So you read the file, check the metadata, and unmarshal the code object. The code object has some metadata and a field (__code__) that contains the bytecode on it. So yes, CPython executes top-level files because they are code objects

@KCreate KCreate changed the title Redesign import system Import statement Mar 31, 2022
KCreate added a commit that referenced this issue Apr 3, 2022
KCreate added a commit that referenced this issue Apr 4, 2022
@KCreate
Copy link
Owner Author

KCreate commented Apr 6, 2022

Implemented via previous commits, export statements are handled in issue #101

Module import atomicity is handled in #106

@KCreate KCreate closed this as completed Apr 6, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants