tccINT もどき

2017-05-29 :  PCクリニック
Python、C言語、Perl、グルコサミン、Firefox
先日(2017-05-03)の記事「tcc - Tiny C Compiler」以降、

さらに、
先日(2017-05-12)の記事「luajit-tcc:Tiny C Compiler ・・・ for LuaJIT」以降

そこそこ tcc を学習して来た。


ここで、ふと、
5年前(2012-11-28)の記事「CINT:C言語インタプリタ」を思い出した。

出来るかどうかは分からないが、
tcc 版 CINT を作りたくなった。

取り敢えず、tccINT と勝手に呼ぶ。
でも、インタプリタでは無い。


手始めに、以下のような手順を考えた:

“tccINT.gsl”なるファイルを用意しておく。


“tccINT.gsl”をエディタで開いて、
指定場所に、tcc ソース・コードを記述する。

一旦“上書き保存”する。

“tccINT.gsl”をダブルクリックして実行する。


これで、インタプリタもどきと(強引に)呼ぶ???


で、
“tccINT.gsl”ファイルに、tcc コードを入力した例:
----- tccINT.gsl -----
C_Prog=[[
/********** 以下に、tcc ソースを記述する **********/
#include <math.h>
int main(){
for( double x=0; x<=3; x+=0.3 ){
printf( "sin(%f)=%f\n", x, sin(x));
}
return 0;
}
/****************** ここまでに ***************/
]]
tcc = require 'tcc' ('libtcc')
TCL = tcc.new()
TCL:set_output_type( 'output_memory' )
TCL:compile_string( C_Prog )
TCL:run{}
TCL:delete()
------------------
_=io.read(1)
と云った感じ。


出来た。自己満足。


本日はここまで。


luajit-tcc 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170420

メール添付ファイル“winmail.dat”なら“Winmail Opener”

2017-05-27 :  PCクリニック
Python、C言語、Perl、グルコサミン、Firefox
某文書ファイルをメールで送ってもらったところ、・・・・・

添付ファイルが winmail.dat と成っていた?

こんなファイルは目にしたことが無く、
どう足掻いても<紙>には復元できなかった。

仕方なく、検索してみたら・・・・・

分かり易いページが見つかった:
winmail.datという添付ファイルを受け取ったときの対処法

それによると、
  winmail.datとは何か
  Winmail.dat ファイルは、リッチ テキスト形式を保持するために使用されます。
  Outlook では、リッチ テキスト形式のメッセージを送信するときに使用します。
  送信中に、メッセージの内容が変更され、受信側のクライアントで書式情報を
  読み取ることができないことがあります。
  また、受信側のクライアントで、winmail.dat ファイルを使用または
  認識できないことがあります。
と云うことで、
  この現象が起きる条件
  これは、Microsoft社のOutlookというメールソフトを使用したユーザーが、
  リッチテキスト形式(RTF)の 電子メールにファイルを添付して送信し、
  受け取った人がOutlook以外のメールソフトで受信すると
  発生することが多い現象です。
だそうです。

<紙>の場合は、当然、Outlook以外のメールソフト


それで、“対処法”が3通り載っている。

  対処法1 テキスト形式のメールで再送信してもらう

  対処法2 Gmailで見る

  対処法3 フリーソフトを使う


“対処法1”は先方に申し訳ない。

“対処法2”はイヤだ。


と云うことで、“Winmail Opener”を導入することにした。


解説(補足):
  Winmail Openerのダウンロード先に指定されているサイト。
  CNETは老舗・有名どころのサイトなので安心なのですが、
  広告にもダウンロードボタンがたくさん出てきてわかりにくい。
  左の方にある緑色のダウンロードボタンが正解。
  また、インストールする際に、
  続けて別のソフトのインストールをおすすめされるので、
  きちんと読んで判断してください。
  (※ フリーソフトなので、・・・・・)
があったので、・・・・・


「Winmail Opener」で検索

“Yahoo! 知恵袋”の
安全なwinmail openerのダウンロード元を教えて下さい。
が見つかった。
これの回答から、

  とりあえず本家:http://www.eolsoft.com/

へ行き、
その中から“Winmail Opener”を探した:

  「Winmail Opener

ここから、

  Download
  You can download ・・・ from our download page.

に行き、ダウンロードするのだが、・・・

右の緑色ボタンではなく、
下の
“Direct link (without Download.com installer)”
から行った。

「winmail_opener.exe」 version: 1.6 2014-03-25 353KB


早速実行(インストール)。


アプリを起動すると、窓が現れるので、
窓の中に“winmail.dat”をドラッグ&ドロップすると、
復元・表示される。

「ファイル」メニューから“保存”が出来る。


メデタシ、目出度し。


本日はここまで。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170412

GSL Shell 学習:“CSV”モジュール

2017-05-26 :  PCクリニック
Python、C言語、Perl、グルコサミン、Firefox
GSL Shell で“CSV”ファイルを読み込む事については、
“GSL Shell 学習”の初期の頃
つまり、昨年4月(2016-04-04)の記事:
GSL Shell 学習:“CSV”ファイル読み込み
で“General Data Tables”を使うと、

  ・・・・・
  ・・・・・
  つまり、
    M = gdt.read_csv( 'hoge.csv' )
  とするだけで、
  'hoge.csv' ファイルを読み込める。
  ・・・・・
  ・・・・・

と書いている。

しかしながら,

  'M' の各要素へのアクセスは?
   v = M:get( r, c )
   M:set( r, c, v )
  の様に ( 1オリジンで、) r 行、c 列 の要素にアクセスできる。

と、些か<紙>の性に合わない。
これは、
テーブルの要素が、数値データに限らずどんな型でも許しているから。


だが、数値データに限定すれば、
もっと、<紙>の気に入る方式を発見した。
今頃に成ってですが、・・・・・


GSL shell documentation」の、
第23章「Comma Separated Values Parsing Utilities」にあった。

  The module csv offers a few useful functions to
   read data files in 'csv' format.
  This latter is a quite popular format used to easily save
   simple tabular data as comma-separated values with several lines.
  This format can be used to exchange data with
   spreadsheets applications.

=== Google翻訳

  モジュールcsvは、'csv' 形式のデータファイルを読み込むための
   いくつかの便利な関数を提供しています。
  後者は、単純な表形式のデータを複数の行でカンマ区切りの値として
   簡単に保存するために使用される非常に一般的な形式です。
  この形式を使用すると、スプレッドシートアプリケーションと
   データを交換できます。

例が載っている:
csv = require 'csv'

-- load some data and save the results in a table
t = csv.read('examples/data/sige-sims-prof.csv')

-- if the data contains only numbers it can be easily converted
-- intro matrix form
m = matrix.def(t)

-- ・・・・・
  Please note that the function returns a table, not a matrix.
  If the table is in rectangular form and if it contains only numbers,
  it can easily be converted into a matrix using the function matrix()
   as shown in the example above.

=== Google翻訳

  この関数は行列ではなくテーブルを返します。
  テーブルが長方形であり、数値のみを含む場合は、
  上の例に示すように関数matrix() を使用して
  簡単に行列に変換できます。


そうすると、
非数値のデータが最初の行のみに存在する場合は、

  m = matrix.def(t)

の前に、

  table.remove(t,1)

を追加すればOKですね。


これで、

  v = m[r][c]
  m[r][c] = v

の様に ( 1オリジンで、) r 行、c 列 の要素にアクセスできる。


蛇足:
ゼロオリジンの r 行、c 列 にアクセスしたいなら。
(1次元配列となるが)

  v = m.data[r*Z+c]
  m.data[r*Z+c] = v

の様になる。( Z は 列数即ち、Z = # m[1] )
( 又は、_, Z = m:dim() )


本日はここまで。


Lua ( GSL Shell ) 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170411

Python & tcc 学習:libtcc 直接使用

2017-05-24 :  PCクリニック
Python、C言語、Perl、グルコサミン、Firefox
先日(2017-05-19)の記事「tcc 学習:libtcc 直接使用(成功)」では、

  ・・・・・
  ・・・・・
  つまり、
  カレントには、(正しい?)use_libtcc_inline_C.gsl ダケで十分。

  結局、以下のコードで十分:
  ・・・・・
  ・・・・・

と云うことで、
libtcc.dll”を直に使うだけで、
所謂インラインCコードが使えた。


なので、
今回は Python での“libtcc 直接使用”に挑戦。


先日の“use_libtcc_inline_C.gsl”の移植と云うこと?

出来たコードは:
# -*- coding: utf-8 -*-
# ---------- use_libtcc.py -----
import ctypes as ct
tcc = ct.CDLL( 'libtcc' )

ST=''' int Add( int x, int y ){
return x + y;
}
'''
relocate_auto = ct.c_void_p(1)

TCL = tcc.tcc_new();
z = tcc.tcc_set_output_type( TCL, 0 );

z = tcc.tcc_compile_string( TCL, ST );
tcc.tcc_relocate( TCL, relocate_auto )

Add_proto = ct.CFUNCTYPE( ct.c_int, ct.c_int, ct.c_int )
Add = Add_proto( tcc.tcc_get_symbol( TCL, 'Add' ) )
# ------------------

z = Add( 2, 5 )
print( z )

# ------------------
tcc.tcc_delete(TCL)
_=raw_input()
これ1本でOK。

コーディング量は Lua に比べて少ない!


本日はここまで。


luajit-tcc 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170408

LuaJIT-tcc 学習:これって、コールバック処理?

2017-05-22 :  PCクリニック
Python、C言語、Perl、グルコサミン、Firefox
前(2017-05-20)の記事「LuaJIT-tcc 学習:利用法まとめ」で、
  ・・・・・
  ・・・・・
  即ち、Cコードで、SUB 関数を定義し、即時に実行する。
  この時、SUB 関数は、
  ・・・・・
  ・・・・・
  パターンB:Lua の 自作 BBB 関数を呼ぶ
  ・・・・・
  ・・・・・
と書いているが、・・・・・

これって、所謂コールバック処理でしょうか?


まあ、それは置いておいて、
今回、データの共有が出来るのか?
確認してみた。

テスト・プログラムはつまらないもの:
メイン処理で作ったテーブルを(上記の)関数でアクセスできるか?
----- L_C_L_global.gsl
tcc = require 'tcc' ( 'libtcc' )
TCL = tcc.new()
TCL:set_output_type( 'output_memory' )
-------------------- 以上は、固定

function Lget(n) return tbl[n] end

-------------------
TCL:add_symbol( 'Lget', Lget, 'double(*)(int)' )

TCL:compile_string [[
double Lget( int );
double Cget( int n ){ return Lget( n ); }
]]
TCL:relocate( 'relocate_auto' )

Cget = TCL:get_symbol( 'Cget', 'double(*)(int)' )
-------------------

tbl = ffi.new( 'double[5]', 0.1, 1.2, 2.3, 3.4, 4.5 )
z = Cget(3) -- Lua から、C を呼ぶ。その C は、Lua を呼ぶ。
-- 「tbl」共有可能か?確認
print( z )
-------------------- 以下は、固定
TCL:delete()
これを実行すると。
結果は 3.4 となる。
これは正解ですネ。


つまり、グローバルデータは使える。

当然のことでしたか?


本日はここまで。


luajit-tcc 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170407

LuaJIT-tcc 学習:利用法まとめ

2017-05-20 :  PCクリニック
Python、C言語、Perl、グルコサミン、Firefox
先日(2017-05-13)の記事「LuaJIT-tcc:例題から学習」で、
幾つかのパターンについて学習したが、
その後の学習結果を含め、“tcc.lua”の利用パターンをまとめた。


最初に、'tcc.lua' モジュールを解読(?)した結果から、・・・・・

'libtcc.dll' の内部にある関数は以下の19個か?
TCCState* tcc_new( void );
void tcc_delete( TCCState* s );
void tcc_set_lib_path( TCCState* s, const char* path );
void tcc_set_error_func( TCCState* s, void* error_opaque, void ( *error_func )( void* opaque, const char* msg ) );
int tcc_set_options( TCCState* s, const char* str );
int tcc_add_include_path( TCCState* s, const char* pathname );
int tcc_add_sysinclude_path( TCCState* s, const char* pathname );
void tcc_define_symbol( TCCState* s, const char* sym, const char* value );
void tcc_undefine_symbol( TCCState* s, const char* sym );
int tcc_add_file( TCCState* s, const char* filename );
int tcc_compile_string( TCCState* s, const char* buf );
int tcc_set_output_type( TCCState* s, int output_type );
int tcc_add_library_path( TCCState* s, const char* pathname );
int tcc_add_library( TCCState* s, const char* libraryname );
int tcc_add_symbol( TCCState* s, const char* name, const void* val );
int tcc_output_file( TCCState* s, const char* filename );
int tcc_run( TCCState* s, int argc, char* *argv );
int tcc_relocate( TCCState* s1, void* ptr );
void* tcc_get_symbol( TCCState* s, const char* name );
これに対して、
'tcc.lua' が公開している関数は19個で、
大半(以下の14)は右から左:
TCCState* tcc_new()
void tcc_delete( s )
void tcc_set_lib_path( s, path )
void tcc_set_error_func( s, opaque, error_func )
int tcc_set_options( s, str )
int tcc_add_include_path( s, pathname )
int tcc_add_sysinclude_path( s, pathname )
void tcc_define_symbol( s, sym, value )
void tcc_undefine_symbol( s, sym )
int tcc_add_file( s, filename )
int tcc_compile_string( s, buf )
int tcc_add_library_path( s, pathname )
int tcc_add_library( s, libraryname )
int tcc_output_file( s, filename )
だが、
以下の5つでは若干の処理を行っている。
set_output_type( s, type )         -- 第2引数は、変換している
relocate( s, ptr ) -- 第2引数は、変換している
add_symbol( s, name, val, ctype ) -- 第3、4引数で処理をしている
get_symbol( s, name, ctype ) -- 第3引数で処理をしている
run( s, t ) -- 第2引数で処理をしている
'libtcc.dll' 直接使用では、
追加の処理が必要。

それで、 <紙>が欲しいのは以下の9個かナ?
TCCState* tcc_new( void );
void tcc_delete( TCCState* s );
int tcc_set_output_type( TCCState* s, int output_type );
int tcc_add_file( TCCState* s, const char* filename );
int tcc_add_symbol( TCCState* s, const char* name, const void* val );
int tcc_compile_string( TCCState* s, const char* buf );
int tcc_relocate( TCCState* s1, void* ptr );
int tcc_output_file( TCCState* s, const char* filename );
void* tcc_get_symbol( TCCState* s, const char* name );
以上を使ったもののまとめ。


初めに、単に DLL ファイルを作るパターンについて、・・・・・
これは、
先日の記事の(2)DLL ファイル( 'k_lib.dll' )を作るパターン

“Add”関数1つを定義した“k_lib.dll”を作る場合:
-------- make_dll.gsl -----------
tcc = require'tcc' ('libtcc')
TCL = tcc.new()
TCL:set_output_type( 'output_dll' )

-- ===== Cコード ===============
TCL:compile_string[[
#include <windows.h>
#define DLLExport __declspec ( dllexport )
DLLExport int Add( int x, int y ){
return x + y;
}
]]
TCL:output_file( 'k_lib.dll' )
TCL:delete()
とする。


次に、Cコードをコンパイルして即時に実行するパターン

当面考えられる全てのパターンを集めた場合を考える。

即ち、Cコードで、SUB 関数を定義し、即時に実行する。

この時、SUB 関数は、
パターンA:C の AAA 関数を呼ぶ
パターンX:Lua の 標準関数(例:math.sin)を呼ぶ
パターンB:Lua の 自作 BBB 関数を呼ぶ
パターンC:既存DLL にある CCC 関数を呼ぶ
これらのパターンを含めるとすると、
----- 以下2行は必須。
tcc = require'tcc' ('libtcc')
TCL = tcc.new()
----------

-- function BBB( x ) return ~ end -- 関数定義 -- パターンB の場合

TCL:set_output_type( 'output_memory' )

-- TCL:add_file( 'k_lib.dll' ) 既存 DLL ファイル -- パターンC の場合

-- TCL:add_symbol( 'BBB', BBB, 'int(*)( int, int )' ) -- パターンB の場合

-- TCL:add_symbol( 'sin', math.sin, 'double(*)(double)' ) -- パターンX の場合

TCL:compile_string [[

// -- double sin( double ) -- プロトタイプ宣言 -- パターンX の場合

// -- ここに、CCC 関数 のプロトタイプ宣言 -- パターンC の場合

// -- ここに、AAA 関数定義の Cコード -- パターンA の場合

double SUB( double x, double y ){ // SUB 関数のコード

double z;

// 各パターン( A, X, B, C ) の関数を利用するCコード

return z;
}
]]

TCL:relocate( 'relocate_auto' )
SUB = TCL:get_symbol( 'SUB', 'double(*)( double, double )' )

----- ここで、SUB を使う LuaJIT のコード

以上。
些か分かりにくいかナ?



ここで、パターンC の場合 に、
add_file 関数で指定するファイル名は、
既存の DLL ファイルの方が良かった。
つまり、
以前(2017-05-13)の記事「LuaJIT-tcc:例題から学習」の様に、
def ファイルを指定すると、
両方のファイルが必要となってしまう。


本日はここまで。


luajit-tcc 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170406,19

tcc 学習:libtcc 直接使用(成功)

2017-05-19 :  PCクリニック
Python、C言語、Perl、グルコサミン、Firefox
前(2017-05-17)の記事「tcc 学習:libtcc 直接使用」では、

  libtcc1.a に関するエラー原因不明。

で終わっていた。


その後の学習で、原因が判明した。


一番大事なことは、

tcc への PATH を登録している場合、
カレントに、libtcc.dll を置いてはダメ。


と云うことでした。


カレントに置かなければ、libtcc1.a を見つける。
なので、libtcc1.a もカレントに置かなくて良い。
(置いても問題ないが、それはムダ)


そうすると、

  tcc_add_library_path( TCL, '.' )

の行もイラナイ。


つまり、
カレントには、(正しい?)use_libtcc_inline_C.gsl ダケで十分。


結局、以下のコードで十分:
----- use_libtcc_inline_C.gsl -----
-------- void* は、正確には TCCState*
ffi.cdef[[
void* tcc_new( void );
int tcc_set_output_type( void* s, int output_type );

int tcc_compile_string( void* s, const char* buf );
int tcc_relocate( void* s1, void* ptr );

void* tcc_get_symbol( void* s, const char* name );
void tcc_delete( void* s );
]]

-- =========================
tcc = ffi.load( 'libtcc' ) -- カレントに libtcc.dll は置かない
relocate_auto = ffi.cast( 'void*', 1 )

charA = |s| ffi.cast( 'char*', s )
-- =========================

TCL = tcc.tcc_new()
tcc.tcc_set_output_type( TCL, 0 ) -- 0 : run in memory

-- ===== Cコード =====
sss = [[ int Add( int x, int y ){
return x + y;
}
]]
tcc.tcc_compile_string( TCL, charA(sss) )

tcc.tcc_relocate( TCL, relocate_auto )

sym = tcc.tcc_get_symbol( TCL, charA('Add') )
Add = ffi.cast( 'int(*)( int, int )', sym )

-- ===== GSL Shell コード =====

z = Add( 2, 5 ); print( z )
print( Add( 10, 5 ) )

-- ===== 後処理 ============
tcc.tcc_delete(TCL)
_=io.read(1)
こんな感じ。

これでスッキリした。


本日はここまで。


luajit-tcc 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170406

tcc 学習:libtcc 直接使用

2017-05-17 :  PCクリニック
Python、C言語、Perl、グルコサミン、Firefox
先日(2017-05-12)の記事:
luajit-tcc:Tiny C Compiler 0.9.26 binding for LuaJIT」では、

  ・・・・・
  ・・・・・
  これって、
  以前(2017-05-03)の記事「tcc - Tiny C Compiler」で書いた、
  “libtcc”を使ったもの?
  ・・・・・
  ・・・・・
  案の定「tcc.lua」1つあれば使える。
  ・・・・・
  ・・・・・

と云うことで、
libtcc”はイラナイのだが、・・・・・

tcc.luaモジュールを学習して、
libtccを直接使ってみることに挑戦。


tcc.luaモジュールの他に、
・ ~/tcc/libtcc/  にある、libtcc.h
と、
・ ~/tcc/examples/ にある、libtcc_test.c
も参照した。


それで、
以前(2017-05-13)の記事「LuaJIT-tcc:例題から学習」で書いた、
“use_inline_C.gsl”を書き直した:
----- use_libtcc_inline_C.gsl -----
-------- void* は、正確には TCCState*
ffi.cdef[[
void* tcc_new( void );
int tcc_set_output_type( void* s, int output_type );
// #define TCC_OUTPUT_MEMORY 0 /* run in memory (default)
// #define TCC_OUTPUT_EXE 1 /* executable file
// #define TCC_OUTPUT_DLL 2 /* dynamic library
// ・・・・・・・・・・・・

int tcc_compile_string( void* s, const char* buf );
int tcc_relocate( void* s1, void* ptr );
// #define TCC_RELOCATE_AUTO (void*)1

void* tcc_get_symbol( void* s, const char* name );
void tcc_delete( void* s );
int tcc_add_library_path( void* s, const char* pathname );
]]

-- =========================
tcc = ffi.load( 'libtcc' ) -- カレントに libtcc.dll を配置
relocate_auto = ffi.cast( 'void*', 1 )

charA = |s| ffi.cast( 'char*', s )
-- =========================

TCL = tcc.tcc_new()
z = tcc.tcc_set_output_type( TCL, 0 )

-- ===== Cコード =====
sss = [[ int Add( int x, int y ){
return x + y;
}
]]
z = tcc.tcc_compile_string( TCL, charA(sss) )

-- この行が無いと、libtcc1.a が見つから無いエラー???
z = tcc.tcc_add_library_path( TCL, '.' ) -- カレントに libtcc1.a も配置

tcc.tcc_relocate( TCL, relocate_auto )

sym = tcc.tcc_get_symbol( TCL, charA('Add') )
Add = ffi.cast( 'int(*)( int, int )', sym )

-- ===== GSL Shell コード =====

z = Add( 2, 5 ); print( z )
print( Add( 10, 5 ) )

-- ===== 後処理 ============
tcc.tcc_delete(TCL)
_=io.read(1)
こんな感じかな。


libtcc1.a に関するエラー原因不明。


本日はここまで。


luajit-tcc 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170405

tcc 学習:オブジェクト性能

2017-05-15 :  PCクリニック
Python、C言語、Perl、グルコサミン、Firefox
前(2017-05-13)の記事「LuaJIT-tcc:例題から学習」に続いて、
今回は、tcc で生成したオブジェクトの性能について学習。


tcc プロセッサ自体の性能については、
先日(2017-05-03)の記事「tcc - Tiny C Compiler」で書いた如く、

 ・FAST! tcc generates x86 code. No byte code overhead.
   Compile, assemble and link several times faster than GCC.
===
 ・早く! tccはx86コードを生成します。
   バイトコードオーバーヘッドはありません。 コンパイル、アセンブル、
   リンクはGCCより数倍高速です。

だそうですね。

そうすると、生成結果のプログラムの実行性能を知りたい。

例によって???
昨年9月(2016-09-23)の記事「LuaJIT vs LLVM/Clang」で書いた、
“フィボナッチ数を求めるプログラム”で実行時間を計測。

計測のためのプログラム:
----- fib.gsl ------
tcc = require'tcc' ('libtcc')
TCL = tcc.new()
TCL:set_output_type( 'output_memory' )
----------------------------
TCL:compile_string [[
int fib( int n ){
if( n < 2 ){ return n;
}else{ return fib(n-1) + fib(n-2);
}
}
]]
TCL:relocate( 'relocate_auto' )
fib = TCL:get_symbol( 'fib', 'int(*)( int )' )
-- ======================

local t=require'time'

Cst=t.time()
print( fib( 39 ) )
Cet=t.time()

print( Cet-Cst ) -- 0.515 秒

-- ====================
TCL:delete()
と云ったもの。

結果は、上記プログラム内コメントの通り。
これは、以前の LLVM/Clang での結果の -O3 無しに相当する。

つまり、
tcc のオブジェクトは、
最適化無し LLVM/Clang のオブジェクトと一緒。
LuaJIT に比べて、約 1.5 倍速い。


tcc は、MinGW に比べて、
コンパイル時間は数倍速く、オブジェクト性能は同等
(最適化機能は無し)
と云うこと?


本日はここまで。


luajit-tcc 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170404

LuaJIT-tcc:例題から学習

2017-05-13 :  PCクリニック
Python、C言語、Perl、グルコサミン、Firefox
前(2017-05-12)の記事「luajit-tcc:Tiny C Compiler ・・・」で書いた、
同梱例題を基に、本格的(?)な学習を行った。

(1)例題の「base.lua」同様に、インラインCコードで関数を定義し、
  その場でそれを使う、GSL Shell プログラム:
  (追加でのファイル出力は無し)
-------- use_inline_C.gsl -----
tcc = require'tcc' ('libtcc')
TCL = tcc.new()
TCL:set_output_type( 'output_memory' )

-- ===== Cコード ==========
TCL:compile_string [[
int Add( int x, int y ){
return x + y;
}
]]
TCL:relocate( 'relocate_auto' )
Add = TCL:get_symbol( 'Add', 'int(*)( int, int )' )

-- ===== GSL Shell コード =======
z = Add( 2, 5 ); print( z )

-- ===== 後処理 =====
TCL:delete()
_=io.read(1)
で、実行は、
「use_inline_C.gsl」ファイルのダブルクリックで可。


(2)例題の「compile_exe.lua」を流用して、
  DLL ファイル( 'k_lib.dll' )を作るもの:
-------- make_dll.gsl -----
tcc = require'tcc' ('libtcc')
TCL = tcc.new()
TCL:set_output_type( 'output_dll' )

-- ===== Cコード =======
C_PG = [[
#include <windows.h>
#define DLLExport __declspec ( dllexport )
DLLExport int Add( int x, int y ){
return x + y;
}
]]
TCL:compile_string( C_PG )
TCL:output_file( 'k_lib.dll' )
TCL:delete()

-----------------------------
-- ===== 以下はテスト用 =====
klib = ffi.load( 'k_lib' )
ffi.cdef[[ int Add( int x, int y ); ]]

z = klib.Add( 2, 5 ); print( z )
_=io.read(1)
で、実行は、
「make_dll.gsl」ファイルのダブルクリックで可。
この時、同時に「k_lib.def」ファイルも出来る。


(3)例題の「add_symbol.lua」を流用して、
  DLL ファイル(例えば上記の'k_lib.dll')を使う Cコードの例:
-------- use_dll_inline_C.gsl ---
tcc = require'tcc' ('libtcc')
TCL = tcc.new()
TCL:set_output_type( 'output_memory' )
TCL:add_file( 'k_lib.def' ) -- DLL 情報

-- ===== Cコード ========
TCL:compile_string [[
int Add( int, int ); // DLL 内 関数プロトタイプ

int L_Add( int x, int y ){
return Add( x, y );
}
]]
TCL:relocate( 'relocate_auto' )
L_Add = TCL:get_symbol( 'L_Add', 'int(*)( int, int )' )

-- ===== GSL Shell コード =======
z = LAdd( 2, 5 ); print( z )

-- ===== 後処理 ==========
TCL:delete()
_=io.read(1)
で、実行は、
「use_dll_inline_C.gsl」ファイルのダブルクリックで可。
但し、'k_lib.def'、'k_lib.dll'も一緒に置いておく。


本日はここまで。


luajit-tcc 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170402,03

luajit-tcc:Tiny C Compiler 0.9.26 binding for LuaJIT

2017-05-12 :  PCクリニック
Python、C言語、Perl、グルコサミン、Firefox
Lua 向けの ライブラリでは、
基本Lua 用と、LuaJIT(GSL Shell)用とで、互換性が無い?

このことは、昨年3月(2016-03-15)の記事:
GSL Shell 学習:LuaJIT で IupLua は …」で書いている。

そして、昨年2月(2016-02-10)の記事:
GSL Shell 学習:LFS モジュール」で書いた、
LFSモジュールは、“LuaJIT”用のもので“Lua”用は別にある。

また、昨年9月(2016-09-05)の記事:
afxLua - MS Windows API Library」で書いた、
afxLuaライブラリは、“LuaJIT”用のもの。


そこで、
「LuaJIT library」で検索していたら、・・・・・

GitHub - Playermet/luajit-iup: IUP binding for LuaJIT
を見つけた。

だが、昨年4月(2016-04-28)の記事:
GSL Shell 学習:“IUP.lua”モジュール自作」で書いた、
自作 'IUP.lua' モジュール と同等?なもの。
イラナイ?


と、・・・・・

1段上を見た:
GitHub - Playermet
すると、
  Pinned repositories
に、
  luajit-tcc
  Tiny C Compiler 0.9.26 binding for LuaJIT
がある。

  “examples”フォルダには、4本のプログラムがある。

で、実質“tcc.lua”モジュール1本???


  Start using
では、
-- Windows
local tcc = require 'tcc' ('libtcc')
local tcc = require 'tcc' ('../some/path/libtcc.dll')
とあり、
その下に10行ちょっとのExample code
が載っている。

これって、
以前(2017-05-03)の記事「tcc - Tiny C Compiler」で書いた、
libtcc”を使ったもの?


早速、(右の「Clone or download」ボタンから)
ダウンロードした。
 「luajit-tcc-master.zip」 2016-01-02 付 4.91KB

ここで ( これまで保留していた ) tcc へのパスを登録した。
<紙>の場合は、D:/TOOL/Euler/tcc/

そうすると、
案の定「tcc.lua」1つあれば使える。
この1本は、“GSL Shell”に登録した。
<紙>の場合は、D:/TOOL/Lua/gsl-shell/gsl-shell/

そして、
4つの例題を試した。
「base.lua」「compile_exe.lua」「run.lua」と
「add_symbol.lua」

起動(実行)は、どこか作業用ディレクトリで、
gsl-shell  base.lua
等々で。


これは面白い。

libtcc”を使って見ようと思っていたが、
より使い勝手の良い“luajit-tcc”を学習しよう。


本日はここまで。


luajit-tcc 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170402

tcc 学習:call_lua51_Gen モジュール作成

2017-05-10 :  PCクリニック
Python、C言語、Perl、グルコサミン、Firefox
前(2017-05-08)の記事「tcc 学習:既存 DLL を呼び出す DLL の作成」に続いて、
tcc の学習。

今回は、call_Lua51 の作成に関して学習。


これまでの学習から、

(1)“tiny_impdef”コマンドで、
  「lua51.dll」から「lua51.def」を作る。


(2)call_Lua51_Gen モジュールを tcc コードで作る:
// ----- call_Lua51_Gen.c -----
#include <windows.h>
#define DLLExport __declspec ( dllexport )

// -- lua51.dll 内 関数

void* luaL_newstate( void );
void luaL_openlibs( void* L );

int luaL_loadfilex( void* L, const char* fname, const char* mode );
int lua_pcall( void* L, int nargs, int nresults, int msgh );

void lua_getfield( void* L, int i , const char* name );
void lua_pushlightuserdata( void* L, void* p );
char* lua_pushstring( void* L, const char* s );

char* lua_tolstring( void* L, int index, size_t* len );
void lua_settop( void* L, int m ); // m == -(n) - 1
void lua_close( void* L );

//----------------
void* L; int z; char* SV; char buf[1025];

DLLExport char* call_Lua( char* PG, char* FN, void* IT, char* ST ){

L = luaL_newstate();
luaL_openlibs( L );

z = luaL_loadfilex( L, PG, "bt" );
z = lua_pcall( L, 0, 0, 0 ); // 1度実行

lua_getfield( L, -10002, FN );
lua_pushlightuserdata( L, IT );
lua_pushstring( L, ST );

lua_pcall( L, 2, 1, 0 ); // 引数 2 個, 戻り値 1 個

SV = lua_tolstring( L, -1, &z ); // 戻り値
strcpy( buf, SV );

lua_settop( L, -2 ); // lua_pop(L,1); 戻り値を pop
lua_close( L );

return buf;

}
これに対して、
tcc  -shared  call_Lua51_Gen.c  lua51.def
コマンドで、「call_Lua51_Gen.dll」を生成。


(3)今作った call_Lua51_Gen を使うメインプログラムを作る:
今回は、取り敢えず“GSL Shell”を使った。
----- call_call_Lua51_Gen_dll.gsl -----
lua = ffi.load( 'call_Lua51_Gen' ) -- call_Lua51 モジュール
ffi.cdef[[
char* call_Lua( char* PG, char* FN, void* IT, char* ST );
]]
charA = |s| ffi.cast( 'char*', s )
Int32 = |s| ffi.cast( 'int32_t', s )
voidA = |s| ffi.cast( 'void*', s ); NULL=voidA(0)

function printf( f, s, ... )
f = f or io.stdout
f:write(s:format(...))
end
-- 以下 Lua5.1 で実行するコード:( 'Lua51_Gen.lua'(下記)必要
-------------------------- 「lfs.dll」「time.lua」も必要
ss1=[[ print('Lua5.1---')
ffi.cdef[[ int rand(void);
double sqrt(double); ]]
ss2=[[
print( ffi.C.rand() ) -- 乱数生成
print( ffi.C.sqrt(3.0) ) -- 平方根算出
print( math.sin(1.0) )
require'lfs'; print( lfs.currentdir() )
t=require'time'; print(t.time())
print(IT[2])
DT=DblA(IT[5]); print(DT[3])
IT[0]=999; SV='ok!'
]]
ST=ss1..']]'..ss2 -- 上記2つの文字列結合 -----

---------------------- インタフェースデータ:
DT=ffi.new('double[5]', 1.1, 2.2, 3.3, 4.4, 5.5 )
IT=ffi.new('int32_t[6]',1,2,3,4,5,0)
IT[5]=Int32(voidA(DT))
-----------------------------------------

SV = lua.call_Lua(charA('Lua51_Gen.lua'),charA('Exec'),voidA(IT),charA(ST))
----------------------------- 中で実行!!!
-----------------------------------------
print( ffi.string(SV) ) -- 戻り値:文字列
print( IT[0] ) ----------- Lua5.1 実行結果
これで行ける。

実行には、
先月(2017-04-17)の記事「call_Lua 似非モジュール:Lua51 汎用・決定版
で作った「Lua51_Gen.lua」も必要。


本日はここまで。


tcc ( Tiny C Compiler ) 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170330

tcc 学習:既存 DLL を呼び出す DLL の作成

2017-05-08 :  PCクリニック
Python、C言語、Perl、グルコサミン、Firefox
前(2017-05-06)の記事「tcc 学習:lua52.dll 利用その他」に続いて、
dll の利用に関して学習。

今回は、既存 DLL を呼び出す DLL の作成に関して学習。

先日(2017-05-05)の記事「tcc 学習:同梱例題その他」で書いた、
既存の“test_dll.dll”から始める。

(1)“tiny_impdef test_dll.dll”コマンドで
  「test_dll.def」を作る

(2)「test_dll.dll」を使う「use_k_dll.c」を作る:
// ----- use_k_dll.c -----
#include <windows.h>
#define DLLExport __declspec ( dllexport )

int Add( int x, int y ); // これは、'test_dll.dll' 内の関数

DLLExport int add2( int x, int y ){
int z = Add( x, y );

char buf[256];
sprintf( buf, "%d", z );
printf( buf );

return 2*z;
}

(3)“tcc -shared use_k_dll.c test_dll.def”コマンドで、
  「use_k_dll.dll」を作る
  「use_k_dll.def」も出来る

(4)「use_k_dll.dll」を使う「Main_use_k_dll.c」を作る:
// ----- Main_use_k_dll.c -----
int add2( int x, int y ); // これは、'use_k_dll.dll' 内の関数

int main(){
int z = add2( 2, 5 );

char buf[256];
sprintf( buf, "%d", z );
printf( buf );

return 0;
}

(5)“tcc Main_use_k_dll.c use_k_dll.def”コマンドで、
  「Main_use_k_dlls.exe」を作る

※※「Main_use_k_dll.exe」の実行には、2つの dll が必要。


更に、
メインプログラムを GSL Shellで作ってみる:
----- Main_use_k_dll.gsl -----
libK = ffi.load('use_k_dll') -- dll 読み込み
---------- 中で、test_dll.dll の Add を呼んでいる

ffi.cdef[[
int add2( int x, int y ); // use_k_dll 内の関数宣言
]]

----------------------------------------------

print( libK.add2( 2, 5 ) ) --- 出来る
の様に、
これまで通りに作れる。


本日はここまで。


tcc ( Tiny C Compiler ) 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170330

tcc 学習:lua52.dll 利用その他

2017-05-06 :  PCクリニック
Python、C言語、Perl、グルコサミン、Firefox
前(2017-05-05)の記事「tcc 学習:同梱例題その他」に続いて、
dll の利用に関して学習。

前回の
  (4)MinGW で作った自作DLL“test_dll.dll”の利用は?
では、
  “DLL”ファイルから“DEF”ファイルを作る。
と書いた。

そこで、
lua52.dllが使えるか?
に挑戦した。


学習した手順通り:
tiny_impdef  lua52.dll
で、“lua52.def”が出来た。

それで、利用コードの一部を書いてみた:
// ----- k0_call_Lua.c -----
int luaL_newstate( void );

int main(){
int L = luaL_newstate();

char buf[256];
sprintf( buf, "%d", L );
printf( buf );

return 0;
}
これで、
“k0_call_Lua.exe”を作る:
tcc  k0_call_Lua.c  lua52.def
そして、
実行。
確かに state L が出来ているようだ。


他に学習したこと:

システムの「kernel32」「user32」「msvcrt」等の“.def”ファイルは、
(<紙>の場合) D:/TOOL/Euler/tcc/lib/ にあった。


新規に、tcc で、DLL を自作する時は、
MinGW ( Relo2 ) で作るような、シンプルなものではダメ。
#include <windows.h>
#define DLLExport __declspec ( dllexport )
DLLExport int add2( int x, int y ){
// ----- 以下省略
}
の様にキッチリ宣言しておかないとダメ。
なお、
tcc  -shared  hoge.c
では、
“hoge.dll”と同時に“hoge.def”も生成される。


本日はここまで。


tcc ( Tiny C Compiler ) 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170329

tcc 学習:同梱例題その他

2017-05-05 :  PCクリニック
Python、C言語、Perl、グルコサミン、Firefox
前(2017-05-03)の記事「tcc - Tiny C Compiler」の後、
ドキュメントに従って、同梱の例題や自前のプログラムを作ってみた。


先ずは、doc フォルダにある「tcc-win32.txt」で学習。


(1)システム PATH に登録:

取り敢えずは DOS 窓内のみで、<紙>の場合は、

  set path=%path%;D:\TOOL\Euler\tcc


(2)同梱サンプルのコンパイル:

examples フォルダにある「fib.c」を作業場所に持ってきた:
#include <stdio.h>
int fib( n ){
if( n <= 2 ) return 1;
else return fib(n-1) + fib(n-2);
}
int main( int argc, char **argv ){
int n;
if( argc < 2 ){
printf("usage: fib n\n"
"Compute nth Fibonacci number\n");
return 1;
}
n = atoi( argv[1] );
printf( "fib(%d) = %d\n", n, fib(n) );
return 0;
}
見た目の変更を加えた。

これに対して、

  tcc fib.c

と打ち込むと、

  tcc.exe

が出来る。

後は普通に実行出来る。

ここで、1行目の #inclede 文は無くても行ける。


更に、
(3)「tcc-win32.txt」には、興味深い事が載っている:

  Using libtcc as JIT compiler in your program

これは、もっと学習が必要ダ。


次に、
3月(2017-03-11)の記事「SpiderMonkey/js-ctypes 学習」でも使っている、
(4)MinGW で作った自作DLL“test_dll.dll”の利用は?

(1) 最初に“test_dll.dll”から“test_dll.def”を作る。
tiny_impdef  test_dll.dll
これだけ。

(2) 利用コードを書く:
// ----- use_dll.c -----
int Add( int x, int y ); // test_dll.dll 内にある関数
int main(){
int z = Add( 2, 5 );

char buf[256];
sprintf( buf, "%d", z );
printf( buf );

return 0;
}
最低限?

そして、.exe を作る
tcc  use_dll.c  test_dll.def
これで、
“use_dll.exe”ができる。

この時、“test_dll.dll”が PATH の通った処にあれば、

“use_dll.exe”は正常に実行できる。


本日はここまで。


tcc ( Tiny C Compiler ) 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170329
おきてがみ/blogram
blogram投票ボタン



おきてがみ

最新記事
カレンダー
05 | 2017/06 | 07
- - - - 1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 -
月別アーカイブ
カテゴリ
最新コメント
検索フォーム
リンク
プロフィール

<紙>

Author:<紙>
ようこそ。
「パソコンヲタクの雑記帳」
もろもろなことを綴っています。
パソコン ヲタクってねくら?
画像は kami でなく kani です。

カウンター(fc2、i2i) /Google Analytics


i2i(from 2010-08-24)
Total =
Today  =  
Yesterday=
アンチエイジング

Google Analytics
ブックマーク