Personal tools
You are here: Home ブログ uchida Categories junk
« December 2010 »
Su Mo Tu We Th Fr Sa
      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 31  
Categories
JavaScript
Go
Ada
Delphi
junk
 
Document Actions

junk

Up one level

Document Actions

UbuntuにGoをインストールしてみた

アリエルでは最近「最新技術に飛びついて注目されようぜ」というムードがあります。
私としてはもっと古い言語を覚えてみたいんですけどね。
AdaとかLEGOとかForthとかIoとかSmalltalkとかAdaとか。

とはいえ知らない言語を使ってみるのは嫌いじゃないんで、今アリエルで最も熱い言語「Go」をさわってみました。
基本はここにある通りですが、いろいろはまったんで書いておきます。
http://golang.org/doc/install.html
大体この人と同じところで躓きました。なのでほとんどこちらの方のサイトのコピペになってしまいました。
http://d.hatena.ne.jp/kidd-number5/20091111/1257939793


まずMercurialのインストール必要がありますが、Synapticからインストールすると少し古いバージョンのものがインストールされます。
こいつはプロキシ経由でhttpsにアクセスできないバグがあるのでインストールしてはいけません。
アリエルでは外部のネットワークに接続するためにプロキシを使用しているため、ここで苦戦しました。
http://d.hatena.ne.jp/ursm/20080820/1219250897

最新版をインストールするにはソースからビルドするかeasy_installでインストールします。
easy_installをインストールするにはez_setup.pyをダウンロードします。
http://labs.unoh.net/2007/04/python.html

Mercurialのビルドにはpython-develが必要です。
Synapticからpython-all-devをインストールします。

プロキシの設定は~/.hgrcにこんな感じ。

[http_proxy]
host=123.45.67.89:1234

あとPATHを設定するので~/.bash_profileに以下を追加して、

export GOROOT=$HOME/go
export GOOS=linux
export GOARCH=386
export GOBIN=$HOME/go/bin
PATH=$PATH:$GOBIN

読み込ませます。

$ source ~/.bash_profile

全部できたらやっとGoのソースを取得できます。

$ hg clone -r release https://go.googlecode.com/hg/ $GOROOT

取得できたらディレクトリの作成

$ mkdir $GOBIN

あとbisonがないとビルドに失敗するのでインストールします。
ビルド

$ ./all.bash

最後に$GOROOT/misc/emacs/以下にあるelファイルをemacsのパスの通ったところにおいてバイトコンパイルします。
そして.emacsファイルに以下を追記します。
(何言ってんのかわかんねえ、って人はこの辺無視してください。アリエルにはemacsって書くと喜ぶ人が多いんです)

(require 'go-mode-load)
(add-hook 'go-mode-hook
'(lambda()
(setq tab-width 4)

GoのトップページにあるHello Worldをコピペしてこんにちは。

$ ~/go/bin/8g hello.go
$ ~/go/bin/8l hello.8
$ ./8.out
Hello, 世界

試しにGo目並べを作ってみました。
「Go目並べ」言いたかっただけです。
gomoku.zip

package main

import (
"bufio";
"os";
"fmt";
"strconv";
"regexp";
)

const BOARD_LENGTH = 20

const PLAYER1 = "*";
const PLAYER2 = "@";

type Board [BOARD_LENGTH*BOARD_LENGTH]int

func (b *Board) Display() {
fmt.Print(" ");
for i := 0; i < BOARD_LENGTH; i++ {
fmt.Printf("%3d", i);
}
fmt.Println();

for i, n := range *b {
x := i % BOARD_LENGTH;
if x == 0 {
fmt.Printf("%3d", i / BOARD_LENGTH);
}

switch n {
case 1: fmt.Printf(" %s", PLAYER1);
case 2: fmt.Printf(" %s", PLAYER2);
default: fmt.Print(" -");
}
if x == BOARD_LENGTH - 1 {
fmt.Println();
}
}
}

func inRange(n int) bool {
return 0 <= n && n < BOARD_LENGTH;
}

func (b *Board) Put(x, y, n int) bool {
if (!inRange(x) || !inRange(y)) {
fmt.Println("out of index");
return false;
}
index := x + y * BOARD_LENGTH;
if b[index] != 0 {
fmt.Println("already put stone");
return false;
}
b[index] = n;
return true;
}

func (b *Board) IsWinner(putx, puty, putn int) bool {
for i := 0; i < 4; i++ {
var xx, yy int;
switch i {
case 0: xx, yy = -1, -1;
case 1: xx, yy = -1, 0;
case 2: xx, yy = 0, -1;
case 3: xx, yy = -1, 1;
}

x, y := putx, puty;
five := 1;
d := 1;
for {
x += (xx * d);
y += (yy * d);
if inRange(x) && inRange(y) &&
b[x + y * BOARD_LENGTH] == putn {
if five++; five >= 5 {
return true;
}
continue;
}

if d == -1 {
break;
}
x, y = putx, puty;
d = -1;
}
}
return false;
}

func main() {
var stones = []string{" ", PLAYER1, PLAYER2};
turn := 1;
board := new(Board);
board.Display();


fmt.Printf("player%d's(%s) turn\n", turn, stones[turn]);

reXY := regexp.MustCompile(`^ *([0-9]+) +([0-9]+) *\n$`);

in := bufio.NewReader(os.Stdin);
for {
lineBuf, err := in.ReadString('\n');
if err != nil {
fmt.Fprintln(os.Stderr, "ReadLine err:", err);
os.Exit(2);
}
line := string(lineBuf);
if line == "exit\n" {
os.Exit(0);
}
params := reXY.MatchStrings(line);

if len(params) > 0 {
x, _ := strconv.Atoi(params[1]);
y, _ := strconv.Atoi(params[2]);
if board.Put(x, y, turn) {
board.Display();
if board.IsWinner(x, y, turn) {
fmt.Printf("player%d win\n", turn);
os.Exit(0);
}

if turn == 1 { turn = 2; }
else { turn = 1; }
fmt.Printf("player%d's(%s) turn\n", turn, stones[turn]);
}
}
}
}

さわってみた感想は次回書きます。
唐突ですが私の得意言語はDelphi(Object Pascal)です。

Category(s)
Go
junk
The URL to Trackback this entry is:
http://dev.ariel-networks.com/Members/uchida/ubuntu306bgo309230a430f330b930c830fc30eb30573066307f305f/tbping

関数内関数欲しいな

(Goを)さわってみた感想は次回書きます。
唐突ですが私の得意言語はDelphi(Object Pascal)です。
Pascalが好きではない人に何か言ってやろうと思ってたんですが、勝てそうにないんで代わりに以前書いたDelphiのプログラムを貼ってお茶を濁すことにしました。

Goで好きになれそうにないところは関数内関数がないあたりです。
とりあえずコード書いて、似たようなコードやレイヤーが違うコードを関数内関数で括り出しといて、汎用的に使えそうならグローバルやprivateな関数にする、というプロセスは慣れるとなかなかいいものです。
Lispもlabelsを使うCommon Lispより普通に関数が書けるSchemeの方が好きです。
ちなみにGoの

var f := func() {
fmt.Printf("closure %c", a[0]);
};

を関数内関数と呼ぶには抵抗があります。最適化と慣れの問題かもしれませんが。

関数内関数を作れるとその関数ポインタをどうするのか、という問題が発生します。
Delphiでは関数内関数のポインタをとれないことにして問題を解決しています。
正確に言うとこんな感じだったはず(未テスト)。

// 普通の関数を変数に入れるのはOK
procedure Hoge;
begin
Writeln('hello');
end;

type
TProc = procedure;
var
hoge: TProc;
begin
hoge := Hoge;
end.
// 関数内関数を変数に入れるのはコンパイルエラー
procedure Test;
procedure Hoge;
begin
Writeln('hello');
end;
var
hoge: TProc;
begin
hoge := Hoge; // コンパイルエラー
end;
// これはOK、ただしHoge内でTestのローカル変数を触ると実行時エラー
procedure Test;
procedure Hoge;
begin
Writeln('hello');
end;
var
hoge: TProc;
begin
hoge := @Hoge;
end;

しかしytqwerty氏の発明した関数内関数渡しの方法を使うと親関数のローカル変数を触れるようになります。
正確に理解できてはいないのですが、関数内関数を呼ぶ時のスタックのポインタを連れ回してCallする前に書き換えてしまう技のようです。

これをつかってprototype.jsのEnumerable的なものをDelphiで作成してみたのがこれです。
enumerable.zip
IEnumerableを実装するとEnumerableをmixinしたのと似たようなことになります。
Javaな人は「interfaceを実装することがなんでmixinなんだ?」と思われるかもしれませんが、Delphiには「委任」という便利な機能があるのです。
(この辺の「Delphiのinterfaceは使えない」という世間の認識に対してもそのうち何か言いたい)

まあ作ってみたはいいものの実用には使わないと思います。
ちなみに最近のDelphiだと無名関数が使えるらしいです。

やっぱり単なる慣れの問題なのかなあ?

Category(s)
junk
Delphi
The URL to Trackback this entry is:
http://dev.ariel-networks.com/Members/uchida/95a26570518595a265706b3230573044306a/tbping

Adaで超いい加減HTTPサーバ

Adaのタスクはもっと評価されいい、のかな?

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Strings.Maps; use Ada.Strings.Maps;
with Ada.Strings.Fixed; use Ada.Strings.Fixed;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Ada.Streams;
with Ada.Streams.Stream_IO;
with GNAT.Sockets;

with Ada.Integer_Text_IO;
use Ada.Integer_Text_IO;

procedure Run_Server is
package GS renames GNAT.Sockets;

CRLF: constant String := ASCII.CR & ASCII.LF;
task type HTTP_Request is
entry Process(Client_Socket: in GS.Socket_Type);
end;

task body HTTP_Request is
Client: GS.Socket_Type;
Connection: GS.Stream_Access;

function Read return String is
Request_Error: exception;

Offset: Ada.Streams.Stream_Element_Count;
Buffer: Ada.Streams.Stream_Element_Array(1..1024);
Result: Unbounded_String := To_Unbounded_String("");
begin
loop
GS.Receive_Socket(Client, Buffer, Offset);
if Natural(Offset) = 0 then
Put_Line("EOF");
raise Request_Error;
end if;

for i in 1..Offset loop
Result := Result & Character'Val(Buffer(i));
end loop;
exit when Tail(Result, 4) = CRLF & CRLF;
end loop;
return To_String(Result);
end;

function Parse_URL(Headers: String) return String is
first: Positive;
last: Natural;
begin
Find_Token(Headers, To_Set(" "), Ada.Strings.Outside, first, last);
Find_Token(Headers(last+1..Headers'Last), To_Set(" "), Ada.Strings.Outside, first, last);

declare
Url: String := Headers(first+1..last);
begin
if Url = "" or else Url(Url'Last) = '/' then
Url := Url & "index.html";
end if;
return Url;
end;
end;

procedure Write(Url: String) is
package ASS_IO renames Ada.Streams.Stream_IO;
File: ASS_IO.File_Type;
begin
ASS_IO.Open(File, ASS_IO.In_File, Url);

declare
File_Stream: ASS_IO.Stream_Access;
Offset: Ada.Streams.Stream_Element_Count;
File_Buffer: Ada.Streams.Stream_Element_Array(1..1024);
begin
String'Write(Connection, "HTTP/1.0 200 OK" & CRLF & CRLF);
File_Stream := ASS_IO.Stream(File);

loop
Ada.Streams.Read(File_Stream.all, File_Buffer, Offset);
exit when Natural(Offset) = 0;

Connection.Write(File_Buffer(1..Offset));
end loop;
ASS_IO.Close(File);
exception
when others => ASS_IO.Close(File);
end;
Put_Line("done");
end;
begin
accept Process(Client_Socket: in GS.Socket_Type) do
Client := Client_Socket;
end Process;
Connection := GS.Stream(Client);

declare
Headers: String := Read;
Url: String := Parse_URL(Headers);
begin
Write(Url);
end;

GS.Close_Socket(Client);
exception
when others =>
GS.Close_Socket(Client);
end;

type HTTP_Request_Access is access HTTP_Request;
Server: GS.Socket_Type;
Server_Address: GS.Sock_Addr_Type;
Client: GS.Socket_Type;
Client_Address: GS.Sock_Addr_Type;
begin
GS.Initialize;
GS.Create_Socket(Server);
Server_Address.Addr := GS.Inet_Addr("127.0.0.1");
Server_Address.Port := 1972;
GS.Bind_Socket(Server, Server_Address);
GS.Listen_Socket(Server);

loop
GS.Accept_Socket(Server, Client, Client_Address);
Put_Line("Request came");
declare
req: HTTP_Request_Access := new HTTP_Request;
begin
req.Process(Client);
end;
end loop;
end;

Goのgoroutine、Adaのタスクと来たら次はScalaのアクターで書くとどうなるのか、是非見てみたいですね。

Category(s)
junk
Ada
The URL to Trackback this entry is:
http://dev.ariel-networks.com/Members/uchida/ada8d853044304452a06e1bhttp30b530fc/tbping

logoでハローワールド

最近logoの入門書を読んだのでちょっと触ってみました。
to hello.Next
PenUp
setheading 90
Forward 50
end

to hello.DrawHa
setheading 90
PenUp
Forward 20
Right 120
PenDown
Forward 40
PenUp
Back 40
Left 120
Forward 10
Right 60
PenDown
Forward 40

PenUp
Back 40
Left 60
Back 30
end

to hello.DrawRo
setheading 90
Forward 5
PenDown
repeat 4 [
Forward 40
Right 90
]

PenUp
Back 5
end

to hello.DrawHyphen
setheading 180
Forward 20
Left 90
Forward 5
PenDown
Forward 40

PenUp
Back 45
Right 90
Back 20
end

to hello.DrawWa
setheading 135
Forward 5
Right 45
PenDown
Forward 10
PenUp
Back 10
PenDown
Left 90
Forward 40
PenUp
Back 40
PenDown
arc 90 40

PenUp
Left 135
Forward 5
end

to hello.DrawRu
setheading 90
Forward 20
Right 90
PenDown
Forward 35
PenUp
Right 90
Forward 10
Right 180
PenDown
arc 90 10
PenUp
Forward 10
Left 90
Forward 35
Right 90
Forward 15
Right 90
PenDown
Forward 45
Left 135
Forward 30

PenUp
Back 30
Right 135
Back 45
Left 90
Back 35
end

to hello.DrawDo
setheading 90
Forward 25
Right 90
PenDown
Forward 45
PenUp
Back 25
Left 60
PenDown
Forward 20

PenUp
Back 20
Right 60
Back 20
Left 90

repeat 2 [
Forward 10
Right 45
PenDown
Forward 5
PenUp
Back 5
Left 45
]

Back 45
end

setPenSize 5
HideTurtle ClearScreen Window FullScreen
hello.DrawHa
hello.Next
hello.DrawRo
hello.Next
hello.DrawHyphen
hello.Next
hello.DrawWa
hello.Next
hello.DrawHyphen
hello.Next
hello.DrawRu
hello.Next
hello.DrawDo

たかがハロワの癖に可読性が悪すぎます。
Category(s)
junk
The URL to Trackback this entry is:
http://dev.ariel-networks.com/Members/uchida/logo30cf30ed30fc30ef30fc30eb/tbping

S式は時代遅れ


http://dev.ariel-networks.com/Members/inoue/lisp-seminar

これからは関数型言語grassです。

warota.grass

wwWWwWWWwWWWWw v
wwWWWwwWwwWWwWWWwWWWWwWWWWWWWwWWWWWWWWw v
wwWWWwwWwwWWwWWWwWWWWwWWWWWwWWWWWWwWWWWWWWwWWWWWWWWwWWWWWWWWWwWWWWWWWWWWwWWWWWWWWWWWwWWWWWWWWWWWWwWWWWWWWWWWWWWwWWWWWWWWWWWWWWwWWWWWWWWWWWWWWWwWWWWWWWWWWWWWWWWwWWWWWWWWWWWWWWWWWWWWWwwwwwwwwwwwwwwwwwwwWwwWWwWWWwWWWWWWWWWWWWWWWWWWWWWWWw v
wwWWwWWWw v
WWWWWwwwwwww
WWWwwwwwwwWwwWWWWWWWWw
WWWWWWWwwwwwwwwwwWwwWWWWWWWWWWwwwwwwwwwwwwWwwWWWWWWWWWWWWWwWWWWWWWWWWWWWWwwww
WWWWWWWWWWWwwwwwwwwwwwwwwwwWwwwWWWWWWWWWWWWWWWWWw
WWWWWWWWWWWWWWWWWWwwwwwwwwww
$ .grass warota.grass
warota

以前私の作ったgrass実装はマルチバイト文字を全く考慮していないため、使う場合は全角を半角に変換するか消してください。

ちなみに顔文字はS式じゃなくてJavaScriptです

warota.grass warota.grass
Size 1 kB - File type application/octet-stream
Category(s)
junk
The URL to Trackback this entry is:
http://dev.ariel-networks.com/Members/uchida/s5f0f306f66424ee39045308c/tbping

Copyright(C) 2001 - 2006 Ariel Networks, Inc. All rights reserved.