■_
ENIX移植プログラマー戦記 ~TOKYO NAMPA STREETからドラクエ2まで~
を読んでるんだけどすげー読みづらい。
「~しない」の「ない」まで漢字にしちゃうとか、
自分で「ここは伏線ですあとででてきます」みたいな書き方とか。
後者はまあそういう「おふざけ」ととれなくはないけど
笑いを取ろうとやってるなら痛々しいし、
本気で「伏線」をそう言うものだと思ってるのなら以下略。
いずれにしてもきちんとした編集さんか、最低でもそれなりの第三者に見てもらうべきだったんじゃないかなあ。
一つ前へ
2016年3月(上旬)
一つ後へ
2016年3月(下旬)
ENIX移植プログラマー戦記 ~TOKYO NAMPA STREETからドラクエ2まで~
を読んでるんだけどすげー読みづらい。
「~しない」の「ない」まで漢字にしちゃうとか、
自分で「ここは伏線ですあとででてきます」みたいな書き方とか。
後者はまあそういう「おふざけ」ととれなくはないけど
笑いを取ろうとやってるなら痛々しいし、
本気で「伏線」をそう言うものだと思ってるのなら以下略。
いずれにしてもきちんとした編集さんか、最低でもそれなりの第三者に見てもらうべきだったんじゃないかなあ。
rhine is designed to be a fast language utilizing the LLVM JIT featuring N-d tensors, first-class functions, and type inference; specifying argument types is enough. It has a full blown AST into which it embeds a UseDef graph.
今月号のソフトウェアデザイン、
特集「今すぐ実践できる良いプログラムの書き方」で対象のプログラミング言語が
C Java C# Ruby JavaScript
てのはどうなんだろう……
ソフトウェアデザイン 2016年 04 月号 [雑誌]
エルミタージュ秋葉原 – レトロが台所に襲来!あっと驚くニキシー管のキッチンタイマー登場
あ、これってもしや…
昨年12月に開催された「コミックマーケット89」で少量頒布され、今月よりホームページにて再版が開始されているものだ。
やはり。
Gradual Typing の訳語ってこれに固まってきてんでしょうか。 漸進的型付け (Gradual Typing) について語る会 - connpass
メソッドオブジェクトを取り出す文法が欲しい、という話。
long long
むかーーーしのGNU ダイジェスト(か Think GNU)で、gcc がこれをサポートするときの
ちょっとした話が載ってたような記憶があるんだけどさてどこだ。
代入を表す記号としての = について
これから数学の一分野である「代数学」の基礎を Swift で実装しながら解説するシリーズを書いてみようと思います。
なぞのわんらいなあ
>ruby -rbigdecimal -e "puts BigDecimal('1').div(BigDecimal('9801'), 200).to_s('F').scan(/../)"
0.
00
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
99
00
01
へー。
本屋で平積みにされてたグラハム・ハンコックの新刊見てかなりびっくりした。 まだ(作家として)生きてたのか… Amazon.co.jp: 神々の魔術 (上) 失われた古代文明の叡智: グラハム・ハンコック, 大地 舜: 本 Amazon.co.jp: 神々の魔術 (下) 失われた古代文明の叡智: グラハム・ハンコック, 大地 舜: 本 神々の指紋は(少なくとも一つ)「大穴」あるのに気づいて 興ざめしちゃったんだよね。
Speaking at the O'Reilly Fluent conference in San Francisco on Wednesday, Eich called WebAssembly the most exciting development he has seen in the past year.
完結編。
for (go = jumps; go; go = release_label(go))
{
for (lbl = labels; lbl; lbl = lbl->next)
if (strcmp(lbl->name, go->name) == 0)
break;
if (lbl)
{
program->v[go->v_index].x.jump_index = lbl->v_index;
}
else
{
if (*go->name)
panic(_("can't find label for jump to `%s'"), go->name);
program->v[go->v_index].x.jump_index = program->v_length;
}
}
jumps = NULL;
外側の for ループでは分岐命令(b とか t とか)にぶら下がっているラベルを 一つ一つ取り出して、 内側の for ループで : を使って定義されたラベルと突き合わせて ジャンプ先の解決をバックパッチしている。 のだけど、b や t のあとにラベルがない、つまりスクリプトの最後へ飛ぶ場合は for のあとの else 部分を実行するのが期待されているのに、 「空のラベルが登録されている」ために then part が実行されてしまう。ということはつまり……
ちなみに FreeBSD の sed では空のラベル定義ができないようになってました。
で。
/* Read a program (or a subprogram within `{' `}' pairs) in and store
the compiled form in `*vector'. Return a pointer to the new vector. */
static struct vector *compile_program P_((struct vector *));
static struct vector *
compile_program(vector)
struct vector *vector;
{
struct sed_cmd *cur_cmd;
struct buffer *b;
int ch;
for (;;)
{
struct addr a;
while ((ch=inchar()) == ';' || ISSPACE(ch))
;
if (ch == EOF)
break;
cur_cmd = next_cmd_entry(&vector);
cur_cmd->cmd = ch;
switch (ch)
{
case ':':
if (cur_cmd->a1)
bad_prog(_(NO_COLON_ADDR));
labels = setup_label(labels, vector->v_length, read_label(), NULL);
break;
case 'T':
case 'b':
case 't':
jumps = setup_label(jumps, vector->v_length, read_label(), NULL);
break;
}
/* this is buried down here so that "continue" statements will miss it */
++vector->v_length;
}
return vector;
}
説明に不要なところは削りまくってるので元のソースコードがこんな 格好ではないのですがそれはとにかく、 : や b、t コマンドが登場したときはそれに続く文字列をラベルとして処理するわけで
/* Store a label (or label reference) created by a `:', `b', or `t'
command so that the jump to/from the label can be backpatched after
compilation is complete, or a reference created by a `{' to be
backpatched when the corresponding `}' is found. */
static struct sed_label *setup_label
P_((struct sed_label *, countT, char *, const struct error_info *));
static struct sed_label *
setup_label(list, idx, name, err_info)
struct sed_label *list;
countT idx;
char *name;
const struct error_info *err_info;
{
struct sed_label *ret = OB_MALLOC(&obs, 1, struct sed_label);
ret->v_index = idx;
ret->name = name;
if (err_info)
MEMCPY(&ret->err_info, err_info, sizeof (ret->err_info));
ret->next = list;
return ret;
}
setup_label はコメントの通りで、 ラベルの読み込みはこっちの read_label の方 (setup_label の呼び出しのところで呼んでます)。
/* read in a label for a `:', `b', or `t' command */
static char *read_label P_((void));
static char *
read_label()
{
struct buffer *b;
int ch;
char *ret;
b = init_buffer();
ch = in_nonblank();
while (ch != EOF && ch != '\n'
&& !ISBLANK(ch) && ch != ';' && ch != CLOSE_BRACE && ch != '#')
ch = add_then_next (b, ch);
savchar(ch);
add1_buffer(b, '\0');
ret = ck_strdup(get_buffer(b));
free_buffer(b);
return ret;
}
行末なり、ファイル末尾なり、空白あるいはコメント開始記号のようなものが 見つかるまでをラベルを構成するものとして取り出すと。 そしてさっきの setup_label でリストに登録しておいて
使うときにこのリストからラベルを見つけ出すのですが
/* Make any checks which require the whole program to have been read.
In particular: this backpatches the jump targets.
Any cleanup which can be done after these checks is done here also. */
void
check_final_program(program)
struct vector *program;
{
struct sed_label *go;
struct sed_label *lbl;
for (go = jumps; go; go = release_label(go))
{
for (lbl = labels; lbl; lbl = lbl->next)
if (strcmp(lbl->name, go->name) == 0)
break;
if (lbl)
{
program->v[go->v_index].x.jump_index = lbl->v_index;
}
else
{
if (*go->name)
panic(_("can't find label for jump to `%s'"), go->name);
program->v[go->v_index].x.jump_index = program->v_length;
}
}
jumps = NULL;
}
おや?
つづく?
3/15 → ガイウス・ユリウス・カエサル - Wikipedia まあ暦が違うんで(同じ日だとするのは)意味ない気もするけど (この辺は日本史上のあれこれなんかも同じ)。
今回も sed のはなし。
GNU sedの変な挙動 - jarp,
名前を省略したラベルを設定するとなぜかそこに飛ぶ。
ということなので調べてみた。
ちなみに
bやtでLABELを省略すると次にサイクルに飛ぶのはman sedやinfo sedにも書いてあるので、
GNU sedの仕様であることは間違いない。
これ、GNU sed に限った話ではなかったりします。
ってまあ「GNU sedの仕様であること」はその通りですが。
sed [2addr]t [label] Test. Branch to the : command bearing the label if any substitutions have been made since the most recent reading of an input line or execution of a t. If label is not specified, branch to the end of the script.[2addr]b [label] Branch to the : command bearing the label. If label is not specified, branch to the end of the script. The implementation supports labels recognised as unique up to at least 8 characters; the actual length (greater than or equal to 8) that is supported by the implementation is unspecified. It is unspecified whether exceeding a label length causes an error or a silent truncation.[2addr]b [label] Branch to the : command bearing the label. If label is not specified, branch to the end of the script. The implementation supports labels recognised as unique up to at least 8 characters; the actual length (greater than or equal to 8) that is supported by the implementation is unspecified. It is unspecified whether exceeding a label length causes an error or a silent truncation. [2addr]t [label] Test. Branch to the : command bearing the label if any substitutions have been made since the most recent reading of an input line or execution of a t. If label is not specified, branch to the end of the script. [0addr]:label This command does nothing; it bears a label for the b and t commands to branch to.[0addr]:label This command does nothing; it bears a label for the b and t commands to branch to.
これを踏まえた上でソースを追いかけると…
つづく。
AlphaGo の強さを見て連想したのは 「一兆クレジット艦隊」 なぜなのか気になったそこの君は 「EURISKO」で検索だ :)
とあるSNSからのメールがspam判定され続けているので、
「なんでこのメールがspam判定されたのか」
ってのを読んでみた。
Be careful with this message. Many people marked similar messages as spam.
っておいw
jot のソースコードから。
while (mask) /* 4 bit mask has 1's where last 4 args were given */
switch (mask) { /* fill in the 0's by default or computation */
case HAVE_STEP:
case HAVE_ENDER:
case HAVE_ENDER | HAVE_STEP:
case HAVE_BEGIN:
case HAVE_BEGIN | HAVE_STEP:
reps = REPS_DEF;
mask |= HAVE_REPS;
break;
case HAVE_BEGIN | HAVE_ENDER:
s = ender > begin ? 1 : -1;
mask |= HAVE_STEP;
break;
case HAVE_BEGIN | HAVE_ENDER | HAVE_STEP:
if (randomize)
reps = REPS_DEF;
else if (s == 0.0)
reps = 0;
else
reps = (ender - begin + s) / s;
if (reps <= 0)
errx(1, "impossible stepsize");
mask = 0;
break;
case HAVE_REPS:
case HAVE_REPS | HAVE_STEP:
begin = BEGIN_DEF;
mask |= HAVE_BEGIN;
break;
case HAVE_REPS | HAVE_ENDER:
s = STEP_DEF;
mask = HAVE_REPS | HAVE_ENDER | HAVE_STEP;
break;
case HAVE_REPS | HAVE_ENDER | HAVE_STEP:
if (randomize)
begin = BEGIN_DEF;
else if (reps == 0)
errx(1, "must specify begin if reps == 0");
begin = ender - reps * s + s;
mask = 0;
break;
case HAVE_REPS | HAVE_BEGIN:
s = STEP_DEF;
mask = HAVE_REPS | HAVE_BEGIN | HAVE_STEP;
break;
case HAVE_REPS | HAVE_BEGIN | HAVE_STEP:
if (randomize)
ender = ENDER_DEF;
else
ender = begin + reps * s - s;
mask = 0;
break;
case HAVE_REPS | HAVE_BEGIN | HAVE_ENDER:
if (reps == 0)
errx(1, "infinite sequences cannot be bounded");
else if (reps == 1)
s = 0.0;
else
s = (ender - begin) / (reps - 1);
mask = 0;
break;
case HAVE_REPS | HAVE_BEGIN | HAVE_ENDER | HAVE_STEP:
/* if reps given and implied, */
if (!randomize && s != 0.0) {
long t = (ender - begin + s) / s;
if (t <= 0)
errx(1, "impossible stepsize");
if (t < reps) /* take lesser */
reps = t;
}
mask = 0;
break;
default:
errx(1, "bad mask");
}
なんというか面白いことやってんな。と。
とある駅の券売機スペース。 かつては10台以上券売機が置かれていたのが 今は7台になっていて、さらにそのうちの3台が PASMO(SUICA)のチャージ専用機。 何のかんの言ってかわってんだねえ。
2日間に渡って、レトロゲームに関する講演・展示・勉強会などを行なうイベントで、SFコンベンションの「はるこん2016」と同時開催になります。 特別講演として、「スペースインベーダーの歴史的意味」、「赤木真澄氏から見たアミューズメント史」、「アーケード黎明期を語る座談会」などの貴重なセッションが予定されています。
著者が日向俊二氏というのがドキドキ感を高めます。
sedの話のつづき。 OS X のあれこれが BSD 由来ということで、 FreeBSD の sed を眺めてみる。
/*-
* Copyright (c) 2013 Johann 'Myrkraverk' Oskarsson.
* Copyright (c) 1992 Diomidis Spinellis.
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Diomidis Spinellis of Imperial College, University of London.
*
(略)
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#ifndef lint
static const char copyright[] =
"@(#) Copyright (c) 1992, 1993\n\
The Regents of the University of California. All rights reserved.\n";
#endif
#ifndef lint
static const char sccsid[] = "@(#)main.c 8.2 (Berkeley) 1/3/94";
#endif
これね。
で、そのオプション解析部分。
int
main(int argc, char *argv[])
{
int c, fflag;
char *temp_arg;
(void) setlocale(LC_ALL, "");
fflag = 0;
inplace = NULL;
while ((c = getopt(argc, argv, "EI:ae:f:i:lnr")) != -1) ←☆☆
switch (c) {
case 'r': /* Gnu sed compat */
case 'E':
rflags = REG_EXTENDED;
break;
case 'I':
inplace = optarg;
ispan = 1; /* span across input files */
break;
case 'a':
aflag = 1;
break;
case 'e':
eflag = 1;
if ((temp_arg = malloc(strlen(optarg) + 2)) == NULL)
err(1, "malloc");
strcpy(temp_arg, optarg);
strcat(temp_arg, "\n");
add_compunit(CU_STRING, temp_arg);
break;
case 'f':
fflag = 1;
add_compunit(CU_FILE, optarg);
break;
case 'i':
inplace = optarg; ←☆☆☆
ispan = 0; /* don't span across input files */
break;
case 'l':
if(setlinebuf(stdout) != 0)
warnx("setlinebuf() failed");
break;
case 'n':
nflag = 1;
break;
default:
case '?':
usage();
}
argc -= optind;
argv += optind;
getopt に渡しているオプション文字列は "EI:ae:f:i:lnr"
なので、-i はオプションに対する引数をとり、それは省略することはできない。
実際 case 'i': のところでも
GNU のとは違って問答無用で inplace = optarg; としている。
再度、GNU sed の同様の部分を見ると
int
main(argc, argv)
int argc;
char **argv;
{
#ifdef REG_PERL
#define SHORTOPTS "bsnrRuEe:f:l:i::V:"
#else
#define SHORTOPTS "bsnruEe:f:l:i::V:" ←☆☆
#endif
static struct option longopts[] = {
{"binary", 0, NULL, 'b'},
{"regexp-extended", 0, NULL, 'r'},
#ifdef REG_PERL
{"regexp-perl", 0, NULL, 'R'},
#endif
{"expression", 1, NULL, 'e'},
{"file", 1, NULL, 'f'},
{"in-place", 2, NULL, 'i'}, ←☆☆☆
{"line-length", 1, NULL, 'l'},
{"quiet", 0, NULL, 'n'},
{"posix", 0, NULL, 'p'},
{"silent", 0, NULL, 'n'},
{"separate", 0, NULL, 's'},
{"unbuffered", 0, NULL, 'u'},
{"version", 0, NULL, 'v'},
{"help", 0, NULL, 'h'},
#ifdef ENABLE_FOLLOW_SYMLINKS
{"follow-symlinks", 0, NULL, 'F'},
#endif
{NULL, 0, NULL, 0}
};
(略)
while ((opt = getopt_long(argc, argv, SHORTOPTS, longopts, NULL)) != EOF)
{
switch (opt)
{
SHORTOPTS の実体に含まれる 'i' には ':' が二つ続いているので オプションに対する引数は「省略可能」。 longopts の "in-place" の行にある 2 も同じ指示をロングオプションに行うもの。
case 'i':
separate_files = true;
if (optarg == NULL)
/* use no backups */
in_place_extension = ck_strdup ("*");
else if (strchr(optarg, '*') != NULL)
in_place_extension = ck_strdup(optarg);
else
{
in_place_extension = MALLOC (strlen(optarg) + 2, char);
in_place_extension[0] = '*';
strcpy (in_place_extension + 1, optarg);
}
break;
optarg == NULL ってのが
オプションに引数が渡されたかどうかの判定。
前回のおまけのおまけ
$ cat >argchk.sh echo $1 echo $2 echo $3 $ bash argchk.sh aaa '' ccc aaa ccc $ bash argchk.sh aaa'' ccc aaa ccc $ bash argchk.sh aaa''ccc ddd aaaccc ddd $ bash argchk.sh aaa' 'ccc ddd aaa ccc ddd
まあこうなってるわけですよ。
一つ前へ
2016年3月(上旬)
一つ後へ
2016年3月(下旬)
リンクはご自由にどうぞ
メールの宛先はこちら