C++ ときどき ごはん、わりとてぃーぶれいく☆

USAGI.NETWORKのなかのひとのブログ。主にC++。

Pro Micro と qmk_firmware と WSL-Ubuntu と avrdude のメモ

自作キーボードを Windows 10 な PC で楽しみたいけど WSL-Ubuntu でにゃんにゃんしたいメモ。

WSL-Ubuntu での AVR 開発環境の準備

sudo apt install -y gcc-avr avr-libc binutils-avr avrdude

WSL-Ubuntu での qmk_firmwaremake によるビルド

git clone git@github.com:qmk/qmk_firmware.git
cd qmk_firmware
make lets_split:default

開発環境に問題がなければ待っているだけ。

ls -la .build/*.hex

.hex ができていなければ開発環境の install に何か忘れているか、 alias なりシェル関数なり PATH の優先順位なりで何かがおかしい。エラーログが出ていれば読んでどうにかする。

-rwxrwxrwx 1 usagi usagi 54K 2019-02-11T08:35:44 .build/lets_split_rev2_default.hex

WSL-Ubuntu での avrdude による Pro Micro への .hex のアップロード

執筆時点の WSL では次のようにポートを指定せず qmk_firmwaremake に全自動でお任せしようとすると ERROR で期待動作しない😂

# これは失敗する例
make lets_split:default:avrdude

ERROR: AVR flashing cannot be automated within the Windows Subsystem for Linux (WSL) currently. Instead, take the .hex file generated and flash it using AVRDUDE, AVRDUDESS, or XLoader.

と、いうわけで、 Pro Micro を RESET しつつ avrdude を手打ちする。長いコマンドになるので予め入力して ENTER するだけにしてから Pro Micro を RESET して素早く ENTER する。 avrdude-P 引数で指定すべき /dev/ttyS 系のポートが具体的にどれなのかはちょっとした注意が必用(後述)。

# これは成功する例
avrdude -p atmega32u4 -c avr109 -P /dev/ttyS4 -U flash:w:/mnt/c/Users/usagi/tmp/GitHub/qmk_firmware/.build/lets_split_rev2_default.hex

(note: -U の引数は先に作った .hex のパスへ読み替えて下さい。必用なら pwd とかで確認してね♥ )

↓アップロード成功のログが流れてくれれば成功😃

Connecting to programmer: .
Found programmer: Id = "CATERIN"; type = S
    Software Version = 1.0; No Hardware Version given.
Programmer supports auto addr increment.
Programmer supports buffered memory access with buffersize=128 bytes.

Programmer supports the following devices:
    Device code: 0x44

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e9587 (probably m32u4)
avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
         To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "/mnt/c/Users/usagi/tmp/GitHub/qmk_firmware/.build/lets_split_rev2_default.hex"
avrdude: input file /mnt/c/Users/usagi/tmp/GitHub/qmk_firmware/.build/lets_split_rev2_default.hex auto detected as Intel Hex
avrdude: writing flash (19566 bytes):

Writing | ################################################## | 100% 1.61s

avrdude: 19566 bytes of flash written
avrdude: verifying flash memory against /mnt/c/Users/usagi/tmp/GitHub/qmk_firmware/.build/lets_split_rev2_default.hex:
avrdude: load data flash data from input file /mnt/c/Users/usagi/tmp/GitHub/qmk_firmware/.build/lets_split_rev2_default.hex:
avrdude: input file /mnt/c/Users/usagi/tmp/GitHub/qmk_firmware/.build/lets_split_rev2_default.hex auto detected as Intel Hex
avrdude: input file /mnt/c/Users/usagi/tmp/GitHub/qmk_firmware/.build/lets_split_rev2_default.hex contains 19566 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 0.58s

avrdude: verifying ...
avrdude: 19566 bytes of flash verified

avrdude: safemode: Fuses OK (E:FB, H:D8, L:FF)

avrdude done.  Thank you.

WSL の /dev/ttyS 系と Pro Micro の RESET の注意点

例えば、Pro Micro の初期状態あるいはファームウェアを再設定するなどして Arduino としてブートしている Pro Micro を PC へ挿しているとき、 WSL の外の Windows のデバイスマネージャーの Ports (COM & LPT)COM5 として認識されていたとしよう。この状態では Arduino IDE で遊んだりする時には COM5 をポートに設定して扱える。

しかし、この状態の Pro Micro へ qml_firmware をアップロードしようと avrdude-P する場合に WSL 内で /dev/ttyS5 とすると接続できずに失敗する。

これは Pro Micro は RESET 状態では別の COM ポートへ認識されるためで、例えば、デバイスマネージャーを凝視しながら Pro Micro を RESET すると COM5 だった認識がリセットで解除された直後は COM4 として認識され、書き込み可能時間が経過するとまた認識が解けて COM5 へ再認識される動作を確認できる。

f:id:USAGI-WRP:20190211090901p:plain

↑RESET直後に再認識された COM4 の Pro Micro

と、いうわけで、この場合は avrdude-P 引数には /dev/ttyS4 を渡してあげると期待動作し、 WSL-Ubuntu だけで意図通り qmk_firmwareavrdude でアップロードできる😃

参考

Pro Micro と Arduino IDE と VSCode と Windows 10 のセットアップのメモ

f:id:USAGI-WRP:20190211075454p:plain

note: Pro Micro は install 前から挿しておいても特に問題ないし、 Windows 10 では COM ポートとして認識される。

install

  1. Arduino IDE を install する。
    • Windows は Installer, ZIP, Store-App から導入方法を選べる。
    • Store-App で install すると install 先ディレクトリーが複雑になりバージョン番号も入って何かと面倒。
    • Installer 版で default の C:\Program Files (x86)\Arduino へ入れると何かと無難。
    • Arduino - Software
  2. Arduino IDE を起動 👉 File 👉 Preference 👉 Additional Boards Manager URLs へ sparkfun の JSON を追加
  3. Arduino IDE 👉 Tool 👉 Board 👉 Board Manager
    • ↑ で追加した sparkfun からのダウンロードが自動的に行われる
    • SparkFun AVR Boards を install
  4. VSCode を起動 👉 Extension に Arduino を追加
  5. VSCode の Preferences 👉 arduino.path へ最初に install した Arduino IDE のパスを定義
    • Installer 版なら C:\Program Files (x86)\Arduino に入っているはず
  6. VSCode を再起動
    • 再起動しないと↑の設定が事実上反映されない事があります。

init project

  1. Arduino プロジェクトのディレクトリーを作るなり開くなりして .ino ソースを適当に書く
    • 適当じゃ困るひとは CTRL + SHIFT + P (コマンドパレット)を開いて 👉 >ard exa などと入れると Arduino Examples を開ける
  2. プロジェクト単位( .vscode/arduino.json )の設定でポートとボードを設定する
    • VSCode ウィンドウ最下部の右側の辺りのステータス表示風の部分でポートやボードを表示・選択できるようになっているのでそこから設定できる
    • またはコマンドパレットへ >ard port とか適当な入力を与えるとそれっぽいコマンドを呼べる
  3. CTRL + SHIFT + P (コマンドパレット) 👉 >Arduino: Upload
    • ボードが動いている、といいね🐰

おまけ

// Pro Micro に表面実装されている TX, RX の LED を適当にピカるだけの実験用コード

const int RXLED = 17;

void setup()
{ }

void loop()
{
  // RX=ON, TX=OFF
  digitalWrite( RXLED, LOW );
  TXLED0;
  delay( 2000 );
  // RX=OFF, TX=ON
  digitalWrite( RXLED, HIGH );
  TXLED1;
  delay( 500 );
}

参考

tetraface Metasequoia ユーザーが Autodesk Fusion 360 を使うときの QUICK SETUP メモ

自作キーボード設計に Metasequoia では少々つらいので Autodesk Fusion 360 を導入しました。趣味の工作で売り上げもへったくれも無いので無償使用できます😃

f:id:USAGI-WRP:20190205023811p:plain

Metasequoia のユーザーは最初の QUICK SETUPCAD ExperienceThinkercad を選択するとそれっぽい操作系なので脳が疲れなくなります。

f:id:USAGI-WRP:20190205024008p:plain

ついで、初期設定として、画面右上の自分のユーザー名をぽちっとして、 Preferences から

f:id:USAGI-WRP:20190208122910p:plain

  • General
    • Default modeling orientationY up
    • Default Orbit typeConstrained Orbit
    • Reverse zoom direction を on へ

変更するとほぼメタセコと変わらない操作モードになります😃

メタセコCreate に相当するプリミティブの生成は MODEL モードで、

f:id:USAGI-WRP:20190205024514p:plain

↓ 例えばメタセコ平面 プリミティブ相当なら SCKETCH PALETTE から Rectangle をぐいぐいっと作って(格子への吸着は SHIFT 押下によるドラッグ操作で可能)

f:id:USAGI-WRP:20190205024302p:plain

↓ それからメタセコ押し出し 相当で立体化するなら Extrude を選んで↑で作った面をぽちっと選んでから矢印をぐいぐいっと

f:id:USAGI-WRP:20190205024747p:plain

すると…

f:id:USAGI-WRP:20190205030926p:plain

できる😃

3DCGのモデリングするひとの世界では、一昔前は下絵ベースで頂点を打つ派、近年はフィーリングなスカルプト派が増えている様子。だけど、わたしはメタセコでも、造形したい物体の部品構造、寸法、そんなような数値による設計の再現みたいな具合で使っていて、人体も立方体と押し出しと曲面生成で作る方が得意でした。

そんなわけで、20年ぶり弱くらいにCADの方の3DCGツールを大真面目に使うことにしたのだけど、特に苦労ないというか…不満ないというか…。まあ、ふつーに使えるよねー(昔より操作性もよくなってるし)、便利ー😃 という感じで楽しめそう。

と、言っても私が設計したい自作キーボード、特に人間工学的な曲面とかそういうの無いというか…むしろ板!穴!ボルト!みたいな無骨設計の予定なのだけど😅

CITIES: SKYLINES の MOD 開発環境の整え方、デバッグ出力の出し方

(note: Windows 10, Visual Studio 2017, STEAM 環境向け)

① MOD 開発環境の整え方

理屈はめんどくさいので解説しないよー😃

  1. CITIES: SKYLINES を STEAM で導入
  2. Visual Studio Installer で Workloads タブの Game development with Unity を導入
  3. Visual Studio で MOD 開発の Class Library プロジェクトを作る。
    • Target Platform = .net Framework 3.5
  4. CITIES: SKYLINES アプリに同梱されている mono.dll をデバッガブルなビルドへ置き換える
  5. Windows環境変数MONO_DEBUGGER_AGENT = transport=dt_socket,address=127.0.0.1:56000,defer=y を追加
  6. Visual Studio の MOD 開発プロジェクトに CITIES: SKYLINES の DLL 参照を追加
    • DLLの場所: C:\Program Files (x86)\Steam\steamapps\common\Cities_Skylines\Cities_Data\Managed
    • MOD に必要最小限のDLL: ICities.dll
  7. 適当なソースへ ICities インターフェースを実装したクラスを定義†してビルド
  8. ビルドした MOD の DLL を %LOCALAPPDATA%\Colossal Order\Cities_Skylines\Addons\Mods\ 以下へ配置
    • \Mods\ore_ore_mod_name\ore_ore_mod.dll のようにディレクトリーを切って放り込んでもよい
  9. STEAM クライアントが既に動作していれば終了させておく(重要: デバッガーが挿さらない場合は忘れている可能性あり)
  10. CITIES: SKYLINES を起動し、 Content Manager の MOD に↑で放り込んだMODが列挙される事を確認
  11. Visual Studio のメニューから Debug 👉 Attach Unity Debugger 👉 Input IP 👉 127.0.0.1:56000 でデバッガーの接続を確認
  12. SKYLINES WIKI - Modding API や CITIES: SKYLINES の DLL をオブジェクトブラウザーで眺めるなどしてお好みの MOD を開発する
    • ビルドのポスト処理で MOD の DLL のコピーを自動化するとかは必要に応じて好きにしてください・w・

†適当なソース例↓

using ICities;

namespace usagi.CitiesSkylines.Example1
{
  public class Example1: IUserMod
  {
    public string Name => "うさぎさんえぐざんぽー1号";
    public string Description => "ヒャッハー!えぐざんぽーだぜ!!";
  }
}

f:id:USAGI-WRP:20190130163624p:plain

f:id:USAGI-WRP:20190130174955p:plain

デバッグ出力の出し方

  1. 参照に追加
    • UnityEngine.dll, Assembly-CSharp.dll, ColossalManaged.dll
  2. デバッグ出力メソッドを叩く
    • Debug.Log ( UnityEngine ) // C:\Program Files (x86)\Steam\steamapps\common\Cities_Skylines\Cities_Data\output_log.txt へ出力される
    • DebugOutputPanel.AddMessage ( Assembly-CSharp, ColossalManaged ) // CITIES: SKYLINES ゲーム中の F7 で表示のデバッグ出力ゲーム内ウィンドウに出力される

実装例:

using ColossalFramework.Plugins;
using ICities;
using UnityEngine;

namespace usagi.CitiesSkylines.Example2
{
  public class Example2: IUserMod, ILoadingExtension
  {
    public string Name => "うさぎさんえぐざんぽー2号";
    public string Description => "見せてもらおうか、CITIES: SKYLINES の MOD のデバッグ出力とやらを!";

    void DebugMessage( string m )
    {
      Debug.Log( m );
      DebugOutputPanel.AddMessage( PluginManager.MessageType.Message, m );
    }    

    public void OnCreated( ILoading loading )
    { DebugMessage( $"UCSE2 てすてす OnCreated; loading={loading}" ); }

    public void OnLevelLoaded( LoadMode mode )
    { DebugMessage( $"UCSE2 てすてす OnLevelLoaded; mode={mode}" ); }

    public void OnLevelUnloading()
    { DebugMessage( "UCSE2 てすてす OnLevelUnloading" ); }

    public void OnReleased()
    { DebugMessage( "UCSE2 てすてす OnReleased" ); }
  }
}

他のログと混ざるので、ログから目grepしやすいように適当にユニークな出力文字列を入れておくとよい。

↓ゲーム中にF7(キーバインドを変更していなければ)で出るやつ

f:id:USAGI-WRP:20190131013641p:plain

参考

  1. Cities:Skylines Modding’s documentation — Cities:Skylines Modding 0.0.1 documentation
  2. https://skylines.paradoxwikis.com/Debugging_Mods

usagi.notes 開発始めてました。

Note: 今回は技術的なはなしはたぶんありません。

Sticky Notes アプリってどうもいまひとつわたしが欲しい納得のアプリが無いのよねー、と数年おきくらいにちょっとアプリを調査しては結局ふだん使いとは別にテキストエディターを用意してメモやコードスニペットをタブなどの機能を使って放り込む、そんな事が続いておりました。

と、いうわけで、今回も昨2018年末にメジャーバージョンアップした Microsoft 製の Sticky Notes の動作確認などして同様にそんなボヤキを抱いていたのですが、「ま、いーかげん1つ作るかー😅」というお気持ちになったので作り始めました。

昨日、今日、そのあたりはアプリの基礎的な脳内設計を起こしつつ、付箋の生成と削除のきほんてきなところ、設定保持、ウィンドウ位置の保持処理などそもそもアプリとしてきほんてきなところ、それからそれから、目に見えるところでは、

Light/Dark的なテーマ機能、

f:id:USAGI-WRP:20190118000245p:plain f:id:USAGI-WRP:20190118000248p:plain f:id:USAGI-WRP:20190118000251p:plain

多言語対応機能

f:id:USAGI-WRP:20190118000254p:plain f:id:USAGI-WRP:20190118000257p:plain

など実装してみました。

まだ主機能が未実装なためリポジトリーを公開していませんが、付箋アプリとしての主機能が整ったら OSS として github に乗せます。今回は多言語対応もシステム上はしているので、特に日本語と英語(USA)の他の言語へ翻訳してくれるコミッターさんも現れてくれると嬉しいなー、なんて思っています。

ちなみに、お楽しみに積んでいたメルヘンフォレストDLCまでクリアーしたし、ACE COMBAT 7 の STEAM 版が発売されるまでにそこそこ作ろうかなーって、そんな思いのもとに作り始めたところでした。が、ちょうどよく zak さんから 「Labyrinth of Refrain: Coven of Dusk / ルフランの地下迷宮と魔女ノ旅団」が STEAM に来ているという情報が送られて来たのでわたしながら先行き不安ですが、ま、それなりに作っていくよー。と、思っています😃

C#, XAML: Windows 10 の Ligth/Dark テーマ状態を確認してそれっぽいテーマを採用するアプリにする方法

// Windows のテーマが Light か Dark か取得するヘルパー
using Microsoft.Win32;
namespace usagi.example
{
  static public class ThemeHelper
  {
    const string WindowsThemeRegistryKeyPath = @"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize";
    const string WindowsThemeRegistryValueName = "AppsUseLightTheme";

    public static bool IsWindowsThemeLight
    {
      get
      {
        var key = Registry.CurrentUser.OpenSubKey( WindowsThemeRegistryKeyPath );
        if ( key == null )
          return true;
        var v = (int)key.GetValue( WindowsThemeRegistryValueName );
        return v > 0;
      }
    }
  }
}
// App 起動時に MyLightTheme または MyDarkTheme を適用
namespace usagi.example
{
  public partial class App: Application
  {
    ResourceDictionary RD { get; } = new ResourceDictionary();
    
    App()
    {
      var theme = ThemeHelper.IsWindowsThemeLight ? "MyLightTheme" : "MyDarkTheme";
      RD.Source = new Uri( $"pack://application:,,,/Themes/{ theme }.xaml" );
      Resources.MergedDictionaries.Add( RD );
    }
  }
}
  • MyLightTheme, MyDarkTheme は .xaml を自分で作らなくても NuGet や github で探して適当なテーマを使うと楽。
  • 複数の .xaml に定義が分かれる場合は rd を配列や List にして用意して Resources.MergedDictionaries.Add するとよい。

References

  1. Dark Theme in WPF – RandomEngy's Tech Blog
  2. WPFアプリケーションの外観をWPFテーマで動的に変更するには? - @IT
  3. ResourceDictionary Class (System.Windows) | Microsoft Docs
  4. Registry Class (Microsoft.Win32) | Microsoft Docs

C#: C# コードから ECMAScript ソースを翻訳&実行する処理系を組み込む方法; WebBrowser, JScript, V8 ( ClearScript )

いくつか手段がある。

  1. ECMAScriptMicrosoft 処理系の1つ ChakraCore を内包する WPFWebBrowser コンポーネントを組み込む方法
  2. ECMAScriptMicrosoft 処理系の1つ JScript を組み込む方法
  3. ECMAScriptGoogle 処理系の V8 を組み込む方法
  4. ECMAScript 処理系を内包する node.js を組み込む方法

など他にもいくらか。

今回は、 WebBrowser, JScript, V8 ( ClearScript ) について簡単な ECMAScript コードを評価する方法を試したので以下にメモを残します😃

1. WebBrowser を使う方法

  • どこかに見えない WebBrowser を配置しておいて裏でこっそり使うなり、コードだけで new して使うなり。
  • お好みの ECMAScript を記述した html を Navigate して InvokeScript †1 する。
    • html はメモリーストリームや string から読ませるのは少し面倒なのでリソースに持っておいて UriNavigate するのが楽。
  • WinForm 版と WPF 版は似たような設計ながら互換性が無いのでいんたーねっつの情報には注意。

C#ECMAScript を実行する方法をぐぐるとたいていこの類似手法が出てくる。この方法はコード例とか示すまでもないかなーと思うし、めんどくさいので実装例は省略。

2. JScript を組み込む方法

  • プロジェクトの References へ Microsoft.JScript Microsoft.CSharp を追加。
  • ↓な感じで使う。ちょっとめんどくさい。
using System.CodeDom.Compiler;
// 任意の ECMAScript を評価できそうなチート的なメソッドを翻訳しておいて
// ユーザーから任意の ECMAScript ソースを受け取って実行結果を取得できるつもりの JScript 実装
var r = 
  ( CodeDomProvider
    .CreateProvider( "JScript" )
    .CompileAssemblyFromSource
      ( new CompilerParameters() { GenerateInMemory = true }
      , @"package _{ class _{ function f( a ) { return eval( a ); } } }"
      )
    .CompiledAssembly
    .CreateInstance( "_._" )
    as dynamic
  ).f( " 1 + 2 + 3 - 4 " )
  // ↑ こういう数値計算とか文字列処理の式がユーザーから飛んでくる分には期待動作します。
  ;
MessageBox.Show( r.ToString() );

dynamic とかたまには使ってみたくなったので使った。 dynamic しない場合は記述量は増えるが、

// assembly を一端保持しておいて
var a = CodeDomPrivider. /* 中略 */ .CompiledAssembly();
// 型(=JScriptのソース定義における `class` )を取得して
var t = a.GetType( "_._" );
// 型のインスタンスを取得して
var i = Activator.CreateInstance( t );
// 型のメンバー・メソッドを実行
var r = t.InvokeMember( "f", System.Reflection.BindingFlags.InvokeMethod, null, i, new object[] { " 1 + 2 + 3 - 4 " } );
// 結果を表示
MessageBox.Show( r.ToString() );

のように実装する事になる。

この実装方法では、任意の ECMAScript コードをユーザーから受け取って実行できそうに視えたかもしれないが、できない。例えば、ユーザーに "function ( a ) { return a * a; }" のように関数オブジェクトのソースを与えさせて、 r.f( 10 ) のように実行して使おうとすると例外で死ぬ。

ユーザーに関数を定義させたい場合は、

// ユーザー入力の想定
var source = @"( a, b ) { return Math.sqrt( ( a * a ) + ( b * b ) ); }";

のような関数の引数と本体の定義を受けて、

// CompileAssemblyFromSource にはこんな具合で包んで関数 f という事にして翻訳させておいて
$"package _{{ class _{{ function f { source } }} }}"

それで使うとか、そういう事になる。

私は JScript には興味がかなり希薄なのでよく知りませんが、少なくとも現在のそれは、 .netソースコード記述言語の1つであり、 C#, VB.net, F# とおそらくほぼ等価な実装を ECMAScript 派生の言語処理系として実装したもの、あるいはそんなようなものなのでしょう。

そういうわけで、 Microsoft 環境での C# 的にはこの方法は ECMAScript らしきスクリプト言語処理系をアプリへ組み込む方法としては、ある意味ではもっとも楽なものの1つかもしれません。ある意味では。

昔から一部界隈にはたいへん忌み嫌われて来た JScript の独自仕様や新しい ECMAScript 標準への追従性、 ChakraCore が廃止されたら処理系はどうなるのか、何かと面倒事の原因を抱え込む危惧をひしひしと感じるので、私はあまり使いたくありませんけどね♥

要求が ECMAScript ではなく、明確に JScript な場合にはもちろんこの方法は最適と思います。また、この方法と同様にして C#, VB.net ソースのスクリプト処理系や、実行時に .net な DLL を翻訳してリンクするとかそういう荒業が必要な場合の参考にはなるかもしれません。

V8 を組み込む方法

  • プロジェクトの References へ NuGet から v8.redist-v141-x64 あるいは開発環境にあわせたそういうのを追加。
    • NuGet から "v8" で検索するとたくさんでてくる。 x86, x64, v140(=vs2015), v141(=vs2017), v120, symbols, redist, full などの組み合わせ。

で簡単に使えるかと思ったのだけど、 icui18n の参照が無いとかで NuGet からの install は失敗するようだった。

f:id:USAGI-WRP:20190116234427p:plain

redist ではなく full でも同様だったし、どこの誰がどうパッケージングした icu が欲しいのか探すのも面倒なので、今回はそもそも別系統の V8 の NuGet パッケージを試す事にした。

  • プロジェクトの References へ NuGet から Microsoft.ClearScript を追加。
    • Microsoft 製の V8 処理系を .net へ組み込むライブラリーらしい。( JScript 互換っぽい表記もあるのが懸念点じゃが…)

f:id:USAGI-WRP:20190116235031p:plain

  • ↓な感じで使う。
using Microsoft.ClearScript.V8;
// 単純な加減算の式を評価する例
var e = new V8ScriptEngine();
var r = e.Evaluate( " 1 + 2 + 3 - 4 " );
MessageBox.Show( r.ToString() );

こんだけ😃

// 関数を評価して dynamic で受けておいて C# 実装側でその関数を実行する例
var e = new V8ScriptEngine();
dynamic f = e.Evaluate( " ( a, b ) => Math.sqrt( a * a + b * b ) " );
var r = f( 3, 4 );
MessageBox.Show( r.ToString() );

わーい簡単だ😃 それにナウい感じの Arrow も使える。さすが愛され続けて頭おかしい高速化と進化を遂げるに至った V8 さんです。

欠点は V8 のアッセンブリー追加によるフットプリントの増加がちょこっと大きいくらいかな。 ClearScript の DLL は 445KB 。参考として JScript の DLL は .net Framework の一部な上、 129KB です。PC向けでは気にするシーンは滅多に無いかもしれません。安心安全で簡潔に使える V8 処理系の恩恵の方がよほど大きいと思います。

ちなみに、 "string".substr(-1) を評価した結果は "g"でした。 Stackoverflow によるとこの挙動は JScript の仕様では "string" になるらしいので試してみましたが、先の JScript でも "g" が得られてしまうのでバグとして修正されたか ECMAScript へ準拠するよう JScript の仕様が修正されたのかもしれません。 †2

また、 ClearScript は Microsoft 製らしさの恩恵と思える点に、 ConsoleWPFコンポーネントなどホスト環境の何かしらを束縛して扱う仕組みが実装されている点も便利が良いかもしれません。そこは私もまだ試していませんので機会があればメモを書こうと思います。†3

参考