Nelua オーバービュー 宣言・制御フロー


本家様

ここからの抜粋&翻訳
Luaとの違いがある場合はそちらも併記します.
ざっくりと簡単な部分だけ導入しておきます.
長いので2つに分けました

コメント

comment.nelua
-- one line comment
--[[
  multi-line comment
]]
--[=[
  multi line comment. `=` can be placed multiple times
  in case you have `[[` `]]` tokens inside the comment.
  it will always match its corresponding token
]=]

変数宣言

variable.nelua
local b = false -- of deduced type 'boolean', initialized to false
local s = 'test' -- of deduced type 'string', initialized to 'test'
local one = 1 --  of type 'integer', initialized to 1
local pi: number = 3.14 --  local pi: number = 3.14 --  of type 'number', initialized to 3.14
print(b,s,one,pi) -- outputs: false test 1 3.14

local hoge, fuga = 10, 20 -- luaと同じく複数宣言への代入が可能
print(hoge, fuga) -- outputs: 10 20
local a, c = 10, true -- 型が違っていても問題ない
print(a, c) -- outputs 10 true
local a: number, c: boolean = 10, true -- 型注釈をつける場合はこうなる
print(a, c) -- outputs 10.0 true number型になったので integerで推測された前回と出力が異なる

local a, b = 1, 2
print(a, b) -- outputs: 1 2
b, a = a, b -- swap values
print(a, b) -- outputs: 2 1

型推論

deducation.nelua
local a -- type will be deduced at scope end
a = 1
a = 2
print(a) -- outputs: 2
-- a = 'Error!' error: compiler deduced type 'any' here, but it's not supported yet, please fix this variable type
-- end of scope, compiler deduced 'a' to be of type 'integer'

同じ変数に異なる型が代入されている場合,コンパイラはその型をany typeと推論します.しかし,any型のサポートは完全ではないため,コンパイルエラーが発生します.将来的には動的型付けされたLuaのコードとNeluaが互換性を持つようにサポートされるでしょう.

エラー行数はコードの空行を無視して表示されているようなので注意が必要かもしれません.

ゼロ初期化

initialize.nelua
local b: boolean -- variable of type 'boolean', initialized to 'false'
local i: integer -- variable of type 'integer', initialized to 0
print(b, i) -- outputs: false 0
initialize.lua
local a
print(a) -- outpus: nil

宣言時の未初期化変数の挙動はC,Luaとは違い,ゼロに初期化されるようになっています.これは言語特徴で紹介した通り,未定義動作を減らそうという試みの一環です.また,後述するアノテーションを利用することで,ゼロ初期化しないようにもできます.

autoによる型推論

initialize.nelua
local a: auto = 1 -- a is deduced to be of type 'integer'

-- uncommenting the following will trigger the compile error:
--   constant value `1.0` is fractional which is invalid for the type 'int64'
--a = 1.0

print(a) -- outputs: 1

アノテーション

関数アノテーション

function_anotation.nelua
local function sum(a: integer, b: integer) <inline> -- C inline function
  return a + b
end
print(sum(1,2)) -- outputs: 3

コンパイル時変数

compile_time.nelua
local a <comptime> = 1 + 2 -- constant variable of value '3' evaluated and known at compile-time
print(a) -- outputs: 3

定数宣言

const.nelua
local x <const> = 1
local a <const> = x
print(a) -- outputs: 1

-- uncommenting the following will trigger the compile error:
--   error: cannot assign a constant variable
--a = 2

その他のアノテーション

variable_anotation.nelua
local a: integer <noinit>-- don't initialize variable to zero
a = 0 -- manually initialize to zero
print(a) -- outputs: 0

local b <volatile> = 1 -- C volatile variable
print(b) -- outputs: 1

シンボル

ローカル宣言

local.nelua
do
  local a = 1
  do
    print(a) -- outputs: 1
  end
end
-- uncommenting this would trigger a compiler error because `a` is not visible:
-- a = 1
local.lua
do
  local a = 1
  print(a) -- outputs: 1
end
print(a) -- outputs: nil

Luaでは,未宣言の変数はnilで処理されていましたが,Neluaではエラーになります.

グローバル宣言

globals.nelua
global global_a = 1
global function global_f()
  return 'f'
end
globals.lua
global_a = 1
function global_f()
  return 'f'
end

Neluaではグローバルでの宣言にはキーワードが必須となります. Luaには存在していないキーワードとなります.

call_globals.nelua
require 'globals'
print(global_a) -- outputs: 1
print(global_f()) -- outputs: f

グローバルなので当然他ファイルからも覗けます.

制御フロー構文

if, break, do, goto, repeat, while

特に変更はありません.

switch

switch.nelua
local a = 1 -- change this to 2 or 3 to trigger other ifs
switch a
case 1 then
  print 'is 1'
case 2, 3 then
  print 'is 2 or 3'
else
  print 'else'
end

待望のswitchステートメントが追加されたようです.コンパイル時点で既知の値を処理する際はswitchのほうがパフォーマンスに優れているようです.また,Cのようにbreakを書く必要はありません.

defer

defer.nelua
do
  defer
    print 'world'
  end
  print 'hello'
end
-- outputs 'hello' then 'world'

Go言語から着想を得ているようです.deferはステートメント終了時に,リソースを解放するために使用されることを意図されています. deferは return, break, continueステートメントの前に逆順で実行されることが保証されています.

Neluaが流行った暁には サルでも分かる deferみたいな記事が乱立してそうですね.

monkey_defer.nelua
local function sum(a: number, b: number) :number
    defer
        print 'calc end'
    end
    defer 
        defer
            print ('input b is', b)
        end
        print ('input a is', a)
    end
    return a + b
end

print (sum(4, 5))
--[[ 
outputs:
input a is      4.0
input b is      5.0
calc end
9.0
]]

先入れ後出し,入れ子で処理されることなどを覚えていれば問題なさそうです.

各種for

for.nelua
for i = 0,5 do
  -- i is deduced to 'integer'
  print(i) -- outputs 0 1 2 3 4 5
end
exclusive_for.nelua
for i=0,<5 do
  print(i) -- outputs 0 1 2 3 4
end

この構文はLuaには存在していない

stepped_for.nelua
for i=5,0,-1 do -- start, end, step
  print(i) -- outputs 5 4 3 2 1 0
end

continue

continue.nelua
for i=1,10 do
  if i<=5 then
    continue
  end
  print(i) -- outputs: 6 7 8 9 10
end

この構文はLuaには存在していない