├── LICENSE ├── README.md ├── nim4colab.py └── setup.py /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Tomohiro 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Nim4Colab 2 | Nim4Colab is a IPython extension to use [Nim language](https://nim-lang.org) on [Google Colaboratory](https://colab.research.google.com/). 3 | 4 | ## How to use 5 | Copy and paste following code to a cell on Google Colaboratory and run. 6 | This code download, install and load Nim4Colab extension. 7 | 8 | ``` 9 | !pip install git+https://github.com/demotomohiro/nim4colab.git 10 | %load_ext nim4colab 11 | ``` 12 | 13 | Then, you can use line and cell magics in Nim4Colab extenson. 14 | 15 | ``` 16 | #Run Nim code with nimc cell magic. 17 | %%nimc 18 | echo "Nim version is ", NimVersion 19 | ``` 20 | 21 | Nim4Colab downloads and installs latest Nim from [Nim nightlies](https://github.com/nim-lang/nightlies) when first time one of Nim4Colab's magic is called. 22 | User code is saved to ``~/code.nim`` file before ``nim`` command is called. 23 | 24 | ## Examples 25 | 26 | Print Nim version: 27 | ``` 28 | %nim -v 29 | ``` 30 | Example output: 31 | ``` 32 | Nim Compiler Version 2.0.1 [Linux: amd64] 33 | Compiled at 2023-12-09 34 | Copyright (c) 2006-2023 by Andreas Rumpf 35 | ``` 36 | 37 | Print Nim devel version: 38 | ``` 39 | %nimdev -v 40 | ``` 41 | Example output: 42 | ``` 43 | Nim Compiler Version 2.1.1 [Linux: amd64] 44 | Compiled at 2023-12-08 45 | Copyright (c) 2006-2023 by Andreas Rumpf 46 | ``` 47 | 48 | Run Nim code and print Nim version: 49 | ``` 50 | %%nimc 51 | echo NimVersion 52 | ``` 53 | Example output: 54 | ``` 55 | Hint: used config file '/root/nim-stable/nim/config/nim.cfg' [Conf] 56 | Hint: used config file '/root/nim-stable/nim/config/config.nims' [Conf] 57 | ...................................................................... 58 | CC: code.nim 59 | Hint: [Link] 60 | Hint: mm: orc; threads: on; opt: none (DEBUG BUILD, `-d:release` generates faster code) 61 | 27611 lines; 0.612s; 30.391MiB peakmem; proj: /root/code.nim; out: /root/code [SuccessX] 62 | Hint: /root/code [Exec] 63 | 2.0.1 64 | ``` 65 | 66 | Run Nim code and print Nim version with devel branch Nim: 67 | ``` 68 | %%nimdevc 69 | echo NimVersion 70 | ``` 71 | Example output: 72 | ``` 73 | Hint: used config file '/root/nim-devel/nim/config/nim.cfg' [Conf] 74 | Hint: used config file '/root/nim-devel/nim/config/config.nims' [Conf] 75 | Hint: mm: orc; threads: on; opt: none (DEBUG BUILD, `-d:release` generates faster code) 76 | 10215 lines; 0.030s; 10.449MiB peakmem; proj: /root/code.nim; out: /root/code [SuccessX] 77 | Hint: /root/code [Exec] 78 | 2.1.1 79 | ``` 80 | 81 | Run code as Nimscript file: 82 | (Nimscript has limitations: https://nim-lang.org/docs/nims.html) 83 | ``` 84 | %%nim e 85 | when nimvm: 86 | echo "Running on NimVM" 87 | else: 88 | echo "Not running on NimVM" 89 | ``` 90 | Example output: 91 | ``` 92 | Hint: used config file '/root/nim-stable/nim/config/nim.cfg' [Conf] 93 | Hint: used config file '/root/nim-stable/nim/config/config.nims' [Conf] 94 | Running on NimVM 95 | Hint: used config file '/root/code.nim' [Conf] 96 | ``` 97 | 98 | ## Cell magics 99 | 100 | ### %%nimc [options] 101 | Compile and run Nim code. 102 | Equivalent to calling ``nim c -r [options] ~/code.nim`` 103 | 104 | ### %%nim command [options] 105 | Equivalent to calling ``nim command [options] ~/code.nim`` 106 | 107 | ### %%nimdevc [options] 108 | Same to ``%%nimc`` but uses devel branch Nim. 109 | 110 | ### %%nimdev command [options] 111 | Same to ``%%nim`` but uses devel branch Nim. 112 | 113 | ## Line magics 114 | 115 | ### %nim [parameters] 116 | Execute ``nim [parameters]``. 117 | 118 | ### %nimdev [parameters] 119 | Execute ``nim [parameters]`` using devel branch Nim. 120 | 121 | ### %nimble [parameters] 122 | Execute ``nimble [parameters]``. 123 | 124 | Refer [Nim Compiler User Guide](https://nim-lang.org/docs/nimc.html). 125 | 126 | ## Samples 127 | - [Basic](https://colab.research.google.com/drive/1aNmsJmgnxz-4yr1hT0ZdHh9-XQ_8dcRk) 128 | - [Make PNG image](https://colab.research.google.com/drive/15w2dtk9QE8QDTsqMeRnWCzR7f2kSseoq) 129 | - [Make animation PNG using EGL & OpenGL](https://colab.research.google.com/drive/1J0B0qVvovrJZJI1OU75jIMUjWnymi_6G) 130 | -------------------------------------------------------------------------------- /nim4colab.py: -------------------------------------------------------------------------------- 1 | from IPython.core.magic import register_cell_magic, register_line_magic, register_line_cell_magic 2 | from IPython.utils import io 3 | import pathlib, shutil, subprocess, urllib.request, json, os, sys 4 | 5 | def download(url, path): 6 | with urllib.request.urlopen(url) as response: 7 | with open(path, 'wb') as outfile: 8 | shutil.copyfileobj(response, outfile) 9 | 10 | def downloadNim(archivePath, label): 11 | f = urllib.request.urlopen("https://api.github.com/repos/nim-lang/nightlies/releases") 12 | tree = json.loads(f.read().decode('utf-8')) 13 | for i in tree: 14 | if not label in i['tag_name']: 15 | continue 16 | for j in i['assets']: 17 | if j['name'].endswith("linux_x64.tar.xz"): 18 | url = j['browser_download_url'] 19 | download(url, archivePath) 20 | return 21 | 22 | def getNimDir(branch, root): 23 | assert(branch == "devel" or branch == "stable") 24 | return root / f"nim-{branch}" / "nim" 25 | 26 | def nimInstallIfNotExist(branch, root): 27 | nimDir = getNimDir(branch, root) 28 | nimExe = nimDir / "bin" / "nim" 29 | if not nimExe.is_file(): 30 | print(f"Installing Nim {branch}") 31 | if branch == "devel": 32 | label = "devel" 33 | else: 34 | # Get latest stable version number 35 | f = urllib.request.urlopen("https://api.github.com/repos/nim-lang/Nim/tags") 36 | tree = json.loads(f.read().decode('utf-8')) 37 | # latestStableVer is a text like 1.4.2 38 | latestStableVer = tree[0]['name'][1:] 39 | x = latestStableVer.find(".") 40 | major = latestStableVer[:x] 41 | y = latestStableVer.find(".", x + 1) 42 | minor = latestStableVer[x + 1: y] 43 | label = f"version-{major}-{minor}" 44 | archivePath = root / f"nim-{branch}.tar.xz" 45 | downloadNim(archivePath, label) 46 | nimParDir = nimDir.parent 47 | pathlib.Path.mkdir(nimParDir) 48 | shutil.unpack_archive(str(archivePath), nimParDir) 49 | for i in nimParDir.glob("nim*"): 50 | i.rename(nimParDir / "nim") 51 | break 52 | print("done") 53 | 54 | def nimBin(exe, param, branch, root = pathlib.Path.home()): 55 | nimInstallIfNotExist(branch, root) 56 | nimDir = getNimDir(branch, root) 57 | nimExe = nimDir / "bin" / exe 58 | newEnv = os.environ.copy() 59 | newEnv['PATH'] = str(nimDir / "bin") + ':' + newEnv['PATH'] 60 | ret = subprocess.run( 61 | str(nimExe) + ' ' + param, 62 | shell = True, 63 | env = newEnv, 64 | stdout = subprocess.PIPE, 65 | stderr = subprocess.STDOUT, 66 | universal_newlines = True 67 | ) 68 | print(ret.stdout) 69 | 70 | def nimRun(param, code, branch): 71 | nimCode = pathlib.Path.home() / "code.nim" 72 | nimCode.write_text(code) 73 | nimBin("nim", param + " " + str(nimCode), branch) 74 | 75 | @register_line_cell_magic 76 | def nim(line, cell = None): 77 | if cell is None: 78 | nimBin("nim", line, "stable") 79 | else: 80 | nimRun(line, cell, "stable") 81 | 82 | @register_line_cell_magic 83 | def nimdev(line, cell = None): 84 | if cell is None: 85 | nimBin("nim", line, "devel") 86 | else: 87 | nimRun(line, cell, "devel") 88 | 89 | @register_cell_magic 90 | def nimc(line, cell): 91 | nimRun("c -r " + line, cell, "stable") 92 | 93 | @register_cell_magic 94 | def nimdevc(line, cell): 95 | nimRun("c -r " + line, cell, "devel") 96 | 97 | @register_line_magic 98 | def nimble(line): 99 | nimBin("nimble", line, "stable") 100 | 101 | @register_line_magic 102 | def nimbledev(line): 103 | nimBin("nimble", line, "devel") 104 | 105 | def load_ipython_extension(ipython): 106 | pass 107 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | 3 | setup( 4 | name="nim4colab", 5 | version="0.1", 6 | py_modules = ['nim4colab'], 7 | url = "https://github.com/demotomohiro/nim4colab", 8 | author = "demotomohiro", 9 | ) 10 | --------------------------------------------------------------------------------