だれが中国をつくったか PHP新書より
夏(か、紀元前1900年頃 - 紀元前1600年頃[注釈 1])は、史書に記された中国最古の王朝
殷(いん、拼音: 、紀元前17世紀頃 - 紀元前1046年)は、古代中国の王朝である
周(しゅう、拼音: 、紀元前1046年頃 - 紀元前256年)は、殷を倒して王朝を開いた
春秋戦国:前771年から前221年まで
秦は前221年に統一に成功
漢は前206年より後220年までつづく
184年:黄巾の乱(太平道)で後漢ががたがたになる
同時期に起こった五斗米道は道教の主流となる
注:中国への仏教伝来はブッダが始めた百年後の前2世紀だが
経典は3世紀に伝来とのこと
道教の理論化に大いに用いられた模様
2世紀の終わりに人口激減あって魏の文帝は河南と山東に漢民族を囲い込んだ。約250万人。
多分全中国でも1500万台となり前の5千万から激減 その後数百年かけて6千万になるが
これが上限で19世紀末を迎える
3世紀初頭より三国時代となるが、魏が統一し晋に継承したが五胡十六国時代で混乱
439年に鮮卑系の北魏が華北・華中を統一 華南は宋で南北朝となる
なお倭の五王の最後の武は502年に中国と交通 608年には答礼の裴 世清が来日
アメタリシヒコ(男)とあっているが、推古女帝の時代。。。。663年に白村江で唐に敗れる
その後の隋・唐は鮮卑系 遼・金・元・明・清のうち明以外は征服王朝といわれるが
明の開祖は家柄すらわからない東北の下層出身
なお、遼は華北のみの支配で華中は征服していない
トルコ系の北宋(岡田説)は金においだされ南宋となり華南に移るが、元に滅ぼされる
唐末期:黄巣(個人名)の乱
元末期:浄土教の一種の白蓮教の乱がおこる(紅巾の乱)
清朝末期:キリスト教系の太平天国の乱、そして義和団(武闘術)の乱
2019年10月19日土曜日
2019年4月18日木曜日
gas-html,firebase, heroku, mongo and node.js and post via html etc
https://tonari-it.com/gas-html-web-page/
tuyanoよりこっちがGAS-HTML詳しい ポイントはversionを常にNewにすること!
firebase deploy of node.js はクジラ飛行机も詳しい
https://qiita.com/t_furu/items/665bea8b657c78ab2a22 :: firebase1
https://html5experts.jp/technohippy/18040/ :: firebase2
------------------------------------------------------------------------------------
heroku deploy of node.js はLibroTuyanoに詳しい
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
mongodb がいかにすごいか
http://dqn.sakusakutto.jp/2012/04/mongodb-batch-javascript.html
------------------------------------------------------------------------
意外にPostの理解が足りんかったのでメモ
--index.html--
tuyanoよりこっちがGAS-HTML詳しい ポイントはversionを常にNewにすること!
firebase deploy of node.js はクジラ飛行机も詳しい
https://qiita.com/t_furu/items/665bea8b657c78ab2a22 :: firebase1
https://html5experts.jp/technohippy/18040/ :: firebase2
------------------------------------------------------------------------------------
heroku deploy of node.js はLibroTuyanoに詳しい
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
mongodb がいかにすごいか
http://dqn.sakusakutto.jp/2012/04/mongodb-batch-javascript.html
------------------------------------------------------------------------
意外にPostの理解が足りんかったのでメモ
--index.html--
<html>
<body>
<form action="http://localhost:3000" method="POST">name<input type="text" name="name"><br/>
age<input type="number" name="age"><br/>
<input type="submit">
</form>
</body>
</html>
--srv.js--node this--
--srv.js--node this--
var http = require('http');
var html = require('fs').readFileSync('index.html');
http.createServer(function(req, res) {
if(req.method === 'GET') {
res.writeHead(200, {'Content-Type' : 'text/html'});
res.end(html);
} else if(req.method === 'POST') {
var data = '';
//POSTデータを受けとる
req.on('data', function(chunk) {data += chunk})
.on('end', function() {
console.log(data);
res.end(html);
})
}
}).listen(3000);
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
以下は参考程度
https://watchcontents.com/realtime-com-js-python/ python-server and client-js---
https://watchcontents.com/realtime-com-js-python/ python-server and client-js---
2019年2月27日水曜日
go concurrent / elixir examples
https://qiita.com/yoshinori_hisakawa/items/50966e9ba2627e5ac124 :: context value
https://qiita.com/yoshinori_hisakawa/items/a6608b29059a945fbbbd :: context cancel
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
https://qiita.com/piacere_ex/items/f7077f0ff1b1a6c7a959 :: elixir input from csv
https://qiita.com/piacere_ex/items/64c2127857599137e8a7:: elixir input to result
https://qiita.com/piacere_ex/items/ef434011d154dc73f0cd:: elixir sum up
https://qiita.com/piacere_ex/items/7c33836f930b63b0444d:: elixir sum up 2
https://github.com/reverentF/programing_elixir : elixir 解答
https://github.com/ElixirCedu/30-days-of-elixir :: elxiir samples
https://qiita.com/sudix/items/f92315f0d3d54be0fa79 :: webmachine samples
https://qiita.com/yoshinori_hisakawa/items/a6608b29059a945fbbbd :: context cancel
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
https://qiita.com/piacere_ex/items/f7077f0ff1b1a6c7a959 :: elixir input from csv
https://qiita.com/piacere_ex/items/64c2127857599137e8a7:: elixir input to result
https://qiita.com/piacere_ex/items/ef434011d154dc73f0cd:: elixir sum up
https://qiita.com/piacere_ex/items/7c33836f930b63b0444d:: elixir sum up 2
https://github.com/reverentF/programing_elixir : elixir 解答
https://github.com/ElixirCedu/30-days-of-elixir :: elxiir samples
https://qiita.com/sudix/items/f92315f0d3d54be0fa79 :: webmachine samples
2019年2月8日金曜日
elixir map & timeout on async async_stream amd scraping
1..100 |> Enum.map(&Task.async(IO, :inspect, [&1])) |> Enum.map(&Task.await/1)
1..100 |> Task.async_stream(IO, :inspect, [], max_concurrency: System.schedulers_online) |> Enum.to_list
ーーーーーーーーーーーーーーーーーーーーーーーーーーー
defmodule Example do
def file_read_of(n) do
if File.exists?("result") do :ok = File.rm("result") end
1..n |> Enum.map(fn n -> "file#{n}" end) |>
Enum.map(fn name -> load_file(name) end)
String.split(File.read!("result"), "\r\n", trim: true) # ! is needed
end
defp load_file(name) do
{:ok, c} = File.read(name)
File.write("result", c, [:append])
end
def foo(n) do
if File.exists?("result") do :ok = File.rm("result") end
1..n |> Enum.map(fn n -> "file#{n}" end) |>
Enum.map( fn name -> (Task.async(fn -> load_file(name) end)) end )
|> Enum.map(&Task.await/1)
String.split(File.read!("result"), "\r\n", trim: true) # ! is needed
end
def goo(n) do
if File.exists?("result") do :ok = File.rm("result") end
1..n |> Enum.map(fn n -> "file#{n}" end) |>
Task.async_stream(fn name -> load_file(name) end, [max_concurrency: 10] ) |>
Enum.map(fn {:ok, val} -> val end) # asyncでは,この冗長関数が不要!
String.split(File.read!("result"), "\r\n", trim: true) # ! is needed
end
def sum(n) do
goo(n) |> Enum.map(fn item -> String.split(item, ",") end)
|> Enum.map(fn ( [word, num] ) -> %{"word" => word, "num" => String.to_integer(num)} end)
|> Enum.reduce(%{}, fn (%{"word" => key, "num" => num} , acc) ->
acc=Map.update(acc, key, num, fn v -> v + num end) end)
# variable acc is unused -- warning occurs but do not mind
# IO.inspect Map.keys(m)
# IO.inspect Map.values(m)
# keyがないときは、初期値は最初値をとる! [%{"word" => "a", "num" => 1},....] に対して
end
end
# fileN aaa,1\r\nという風になっておりtrim:trueしないと””がふくまれてしまう
# Map.update(m, key, 0, fn v -> v + 1 end)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
いずれも、タイムアウトは5秒でデフォルトだ つまり、非同期はかなり軽い処理に限定
defmodule FIO do
def fw(n) do
:timer.sleep(4990) #5000近くなるとタイムアウト頻発,
#ファイルだけできて書き込まれない事態もおこってしまう
File.write "file#{n}", "1"
end
end
defmodule Parallel do
def pmap(collection, func) do
collection
|> Enum.map(&(Task.async(fn -> func.(&1) end)))
|> Enum.map(&Task.await/1)
end
end
# Parallel.pmap(1..10,fn(n) -> FIO.fw "file#{n}" end)
defmodule Parallel2 do
def pmap(collection, m,f) do
collection |>
# Task.async_stream(m, f, [], [max_concurrency: 10, timeout: :infinity])
Task.async_stream(m, f, [], [max_concurrency: 10])
# []に1..nが順にはいっていく
|> Enum.map(fn {:ok, :ok} -> 1 end) # 適当な関数!
end
end
# Parallel2.pmap(1..10,FIO,:fw)
# timeout: :infinityをいれたらOKだが
--------------------------------------------------------------------------------
https://www.souya.biz/blog2/pinevillage/2017/02/14/elixir%E3%81%A7%E3%82%AF%E3%83%AD%E3%83%BC%E3%83%A9%E3%83%BC%E4%BD%9C%E6%88%90-%E3%82%B9%E3%82%AF%E3%83%AC%E3%82%A4%E3%83%94%E3%83%B3%E3%82%B0%E7%B7%A8/ => scraing example site
2019年1月19日土曜日
ウェブソケット json api server by elixir
https://shotat.hateblo.jp/entry/2016/09/25/000000
phoenix1.2のチャットの前半が動いた! 嬉しいサイト!
https://github.com/dddrb/phoenix-channel-example/blob/master/README.md
これもV1.2の感動サイト 嬉しい
http://tt-house.com/2013/09/node-js-websocket-interval.html
https://qiita.com/eighty8/items/47243fbdad9b4dfdc301
=>json api serverr by phoenix1.2
:new, :edit not installed at json-api
:: as ReadAll by index()
curl -X GET "http://localhost:4000/api/todos"
:: as ReadOne by show()
curl -X GET "http://localhost:4000/api/todos/2"
:: as Create by create()
curl "http://localhost:4000/api/todos" -X POST -d "todo[description]='clean'" -d "todo[complete]=false"
:: as Update by update()
curl "http://localhost:4000/api/todos/1" -X PUT/PATCH -d "todo[description]='cleaning'" -d "todo[complete]=false"
:: as Delete by delete()
curl -X DELETE "http://localhost:4000/api/todos/1"
これでCRUD完成 Curl is great
phoenix1.2のチャットの前半が動いた! 嬉しいサイト!
https://github.com/dddrb/phoenix-channel-example/blob/master/README.md
これもV1.2の感動サイト 嬉しい
http://tt-house.com/2013/09/node-js-websocket-interval.html
Node.jsを使ってWebSocketで定期的にサーバーからブラウザにプッシュする
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーhttps://qiita.com/eighty8/items/47243fbdad9b4dfdc301
=>json api serverr by phoenix1.2
:new, :edit not installed at json-api
:: as ReadAll by index()
curl -X GET "http://localhost:4000/api/todos"
:: as ReadOne by show()
curl -X GET "http://localhost:4000/api/todos/2"
:: as Create by create()
curl "http://localhost:4000/api/todos" -X POST -d "todo[description]='clean'" -d "todo[complete]=false"
:: as Update by update()
curl "http://localhost:4000/api/todos/1" -X PUT/PATCH -d "todo[description]='cleaning'" -d "todo[complete]=false"
:: as Delete by delete()
curl -X DELETE "http://localhost:4000/api/todos/1"
これでCRUD完成 Curl is great
2018年12月16日日曜日
curl elixir/concurrent and gorm/gin
http://d.hatena.ne.jp/thata/20100207/1265554365 about Curl command
---------------------------------------------------------------------
https://rei19.hatenablog.com/entry/2015/09/08/093606 elixir lang mix-otpの詳述
大変参考になる
エリクサーは1.6以上では無料電子ブックが公開されている
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
https://qiita.com/mochizukikotaro/items/b09116e0ad2d30e37098 :: gorm
https://medium.com/@cgrant/developing-a-simple-crud-api-with-go-gin-and-gorm-df87d98e6ed1 :: RESTful-Api Server by gin
package main
import (
"fmt"
"sync"
// "time"
)
func main() {
type value struct {
mu sync.Mutex
value int
}
var wg sync.WaitGroup
printSum := func(v1, v2 *value) {
defer wg.Done()
v1.mu.Lock()
defer v1.mu.Unlock()
// time.Sleep(2*time.Second)
v2.mu.Lock()
defer v2.mu.Unlock()
fmt.Printf("sum=%v\n", v1.value + v2.value)
}
var a, b value
wg.Add(2)
go printSum(&a, &b)
go printSum(&b, &a) // if (&a, &b), no problem
wg.Wait()
} // のところをはずすとデッドロック発生
---------------------------------------------------------------------
https://rei19.hatenablog.com/entry/2015/09/08/093606 elixir lang mix-otpの詳述
大変参考になる
エリクサーは1.6以上では無料電子ブックが公開されている
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
https://qiita.com/mochizukikotaro/items/b09116e0ad2d30e37098 :: gorm
https://medium.com/@cgrant/developing-a-simple-crud-api-with-go-gin-and-gorm-df87d98e6ed1 :: RESTful-Api Server by gin
package main
import (
"fmt"
"sync"
// "time"
)
func main() {
type value struct {
mu sync.Mutex
value int
}
var wg sync.WaitGroup
printSum := func(v1, v2 *value) {
defer wg.Done()
v1.mu.Lock()
defer v1.mu.Unlock()
// time.Sleep(2*time.Second)
v2.mu.Lock()
defer v2.mu.Unlock()
fmt.Printf("sum=%v\n", v1.value + v2.value)
}
var a, b value
wg.Add(2)
go printSum(&a, &b)
go printSum(&b, &a) // if (&a, &b), no problem
wg.Wait()
} // のところをはずすとデッドロック発生
2018年8月23日木曜日
関数電卓、二分探索(広井を改訂)
//
// calc2.go : 電卓プログラム (変数、組み込み関数の追加)
//
// Copyright (C) 2014 Makoto Hiroi
//
package main
import (
"fmt"
"os"
"math"
"text/scanner"
)
// 値
type Value float64
// 構文木の型
type Expr interface {
Eval() Value
}
// 評価
func (e Value) Eval() Value {
return e
}
// 単項演算子
type Op1 struct {
code rune
expr Expr
}
func newOp1(code rune, e Expr) Expr {
return &Op1{code, e}
}
func (e *Op1) Eval() Value {
v := e.expr.Eval()
if e.code == '-' {
v = -v
}
return v
}
// 二項演算子
type Op2 struct {
code rune
left, right Expr
}
func newOp2(code rune, left, right Expr) Expr {
return &Op2{code, left, right}
}
func (e *Op2) Eval() Value {
x := e.left.Eval()
y := e.right.Eval()
switch e.code {
case '+': return x + y
case '-': return x - y
case '*': return x * y
case '/': return x / y
default:
panic(fmt.Errorf("invalid op code"))
}
}
// 変数
type Variable string
// 大域的な環境
var globalEnv = make(map[Variable]Value)
// 変数の評価
func (v Variable) Eval() Value {
val, ok := globalEnv[v]
if !ok {
panic(fmt.Errorf("unbound variable: %v", v))
}
return val
}
// 代入演算子
type Agn struct {
name Variable
expr Expr
}
func newAgn(v Variable, e Expr) *Agn {
return &Agn{v, e}
}
// 代入演算子の評価
func (a *Agn) Eval() Value {
val := a.expr.Eval()
globalEnv[a.name] = val
return val
}
// 組み込み関数
type Func interface {
Argc() int
}
type Func1 func(float64) float64
func (f Func1) Argc() int {
return 1
}
type Func2 func(float64, float64) float64
func (f Func2) Argc() int {
return 2
}
// 組み込み関数の構文
type App struct {
fn Func
xs []Expr
}
func newApp(fn Func, xs []Expr) *App {
return &App{fn, xs}
}
// 組み込み関数の評価
func (a *App) Eval() Value {
switch f := a.fn.(type) {
case Func1:
x := float64(a.xs[0].Eval())
return Value(f(x))
case Func2:
x := float64(a.xs[0].Eval())
y := float64(a.xs[1].Eval())
return Value(f(x, y))
default:
panic(fmt.Errorf("function Eval error"))
}
}
// 組み込み関数の初期化
var funcTable = make(map[string]Func)
func initFunc() {
funcTable["sqrt"] = Func1(math.Sqrt)
funcTable["sin"] = Func1(math.Sin)
funcTable["cos"] = Func1(math.Cos)
funcTable["tan"] = Func1(math.Tan)
funcTable["sinh"] = Func1(math.Sinh)
funcTable["cosh"] = Func1(math.Cosh)
funcTable["tanh"] = Func1(math.Tanh)
funcTable["asin"] = Func1(math.Asin)
funcTable["acos"] = Func1(math.Acos)
funcTable["atan"] = Func1(math.Atan)
funcTable["atan2"] = Func2(math.Atan2)
funcTable["exp"] = Func1(math.Exp)
funcTable["pow"] = Func2(math.Pow)
funcTable["log"] = Func1(math.Log)
funcTable["log10"] = Func1(math.Log10)
funcTable["log2"] = Func1(math.Log2)
}
// 字句解析
type Lex struct {
scanner.Scanner
Token rune
}
func (lex *Lex) getToken() {
lex.Token = lex.Scan()
}
// 引数の取得
func getArgs(lex *Lex) []Expr {
e := make([]Expr, 0)
if lex.Token != '(' {
panic(fmt.Errorf("'(' expected"))
}
lex.getToken()
if lex.Token == ')' {
lex.getToken()
return e
}
for {
e = append(e, expression(lex))
switch lex.Token {
case ')':
lex.getToken()
return e
case ',':
lex.getToken()
default:
panic(fmt.Errorf("unexpected token in argument list"))
}
}
}
// 因子
func factor(lex *Lex) Expr {
switch lex.Token {
case '(':
lex.getToken()
e := expression(lex)
if lex.Token != ')' {
panic(fmt.Errorf("')' expected"))
}
lex.getToken()
return e
case '+':
lex.getToken()
return newOp1('+', factor(lex))
case '-':
lex.getToken()
return newOp1('-', factor(lex))
case scanner.Int, scanner.Float:
var n float64
fmt.Sscan(lex.TokenText(), &n)
lex.getToken()
return Value(n)
case scanner.Ident:
name := lex.TokenText()
lex.getToken()
if name == "quit" {
panic(name)
}
v, ok := funcTable[name]
if ok {
xs := getArgs(lex)
if len(xs) != v.Argc() {
panic(fmt.Errorf("wrong number of arguments: %v", name))
}
return newApp(v, xs)
} else {
return Variable(name)
}
default:
panic(fmt.Errorf("unexpected token: %v", lex.TokenText()))
}
}
// 項
func term(lex *Lex) Expr {
e := factor(lex)
for {
switch lex.Token {
case '*':
lex.getToken()
e = newOp2('*', e, factor(lex))
case '/':
lex.getToken()
e = newOp2('/', e, factor(lex))
default:
return e
}
}
}
// 式
func expr1(lex *Lex) Expr {
e := term(lex)
for {
switch lex.Token {
case '+':
lex.getToken()
e = newOp2('+', e, term(lex))
case '-':
lex.getToken()
e = newOp2('-', e, term(lex))
default:
return e
}
}
}
func expression(lex *Lex) Expr {
e := expr1(lex)
if lex.Token == '=' {
v, ok := e.(Variable)
if ok {
lex.getToken()
return newAgn(v, expression(lex))
} else {
panic(fmt.Errorf("invalid assign form"))
}
}
return e
}
// 式の入力と評価
func toplevel(lex *Lex) (r bool) {
r = false
defer func(){
err := recover()
if err != nil {
mes, ok := err.(string)
if ok && mes == "quit" {
r = true
} else {
fmt.Fprintln(os.Stderr, err)
for lex.Token != ';' {
lex.getToken()
}
}
}
}()
for {
fmt.Print("Calc> ")
lex.getToken()
e := expression(lex)
if lex.Token != ';' {
panic(fmt.Errorf("invalid expression"))
} else {
fmt.Println(e.Eval())
}
}
return r
}
func main() {
var lex Lex
lex.Init(os.Stdin)
initFunc()
for {
if toplevel(&lex) { break }
}
}
// 二分探索の改正
// 二分探索
def bsearch(x, v, low, high)
let
result = 0
in
while low <= high and result == 0 do
let
mid = (low + high) / 2
in
if v[mid] == x then
begin result = 1,high = -1 end
else
if v[mid] < x then
low = mid + 1
else
high = mid - 1
end
end
end
end,
result
end
end
def binarySearch(x, v)
bsearch(x, v, 0, len(v) - 1)
end
// calc2.go : 電卓プログラム (変数、組み込み関数の追加)
//
// Copyright (C) 2014 Makoto Hiroi
//
package main
import (
"fmt"
"os"
"math"
"text/scanner"
)
// 値
type Value float64
// 構文木の型
type Expr interface {
Eval() Value
}
// 評価
func (e Value) Eval() Value {
return e
}
// 単項演算子
type Op1 struct {
code rune
expr Expr
}
func newOp1(code rune, e Expr) Expr {
return &Op1{code, e}
}
func (e *Op1) Eval() Value {
v := e.expr.Eval()
if e.code == '-' {
v = -v
}
return v
}
// 二項演算子
type Op2 struct {
code rune
left, right Expr
}
func newOp2(code rune, left, right Expr) Expr {
return &Op2{code, left, right}
}
func (e *Op2) Eval() Value {
x := e.left.Eval()
y := e.right.Eval()
switch e.code {
case '+': return x + y
case '-': return x - y
case '*': return x * y
case '/': return x / y
default:
panic(fmt.Errorf("invalid op code"))
}
}
// 変数
type Variable string
// 大域的な環境
var globalEnv = make(map[Variable]Value)
// 変数の評価
func (v Variable) Eval() Value {
val, ok := globalEnv[v]
if !ok {
panic(fmt.Errorf("unbound variable: %v", v))
}
return val
}
// 代入演算子
type Agn struct {
name Variable
expr Expr
}
func newAgn(v Variable, e Expr) *Agn {
return &Agn{v, e}
}
// 代入演算子の評価
func (a *Agn) Eval() Value {
val := a.expr.Eval()
globalEnv[a.name] = val
return val
}
// 組み込み関数
type Func interface {
Argc() int
}
type Func1 func(float64) float64
func (f Func1) Argc() int {
return 1
}
type Func2 func(float64, float64) float64
func (f Func2) Argc() int {
return 2
}
// 組み込み関数の構文
type App struct {
fn Func
xs []Expr
}
func newApp(fn Func, xs []Expr) *App {
return &App{fn, xs}
}
// 組み込み関数の評価
func (a *App) Eval() Value {
switch f := a.fn.(type) {
case Func1:
x := float64(a.xs[0].Eval())
return Value(f(x))
case Func2:
x := float64(a.xs[0].Eval())
y := float64(a.xs[1].Eval())
return Value(f(x, y))
default:
panic(fmt.Errorf("function Eval error"))
}
}
// 組み込み関数の初期化
var funcTable = make(map[string]Func)
func initFunc() {
funcTable["sqrt"] = Func1(math.Sqrt)
funcTable["sin"] = Func1(math.Sin)
funcTable["cos"] = Func1(math.Cos)
funcTable["tan"] = Func1(math.Tan)
funcTable["sinh"] = Func1(math.Sinh)
funcTable["cosh"] = Func1(math.Cosh)
funcTable["tanh"] = Func1(math.Tanh)
funcTable["asin"] = Func1(math.Asin)
funcTable["acos"] = Func1(math.Acos)
funcTable["atan"] = Func1(math.Atan)
funcTable["atan2"] = Func2(math.Atan2)
funcTable["exp"] = Func1(math.Exp)
funcTable["pow"] = Func2(math.Pow)
funcTable["log"] = Func1(math.Log)
funcTable["log10"] = Func1(math.Log10)
funcTable["log2"] = Func1(math.Log2)
}
// 字句解析
type Lex struct {
scanner.Scanner
Token rune
}
func (lex *Lex) getToken() {
lex.Token = lex.Scan()
}
// 引数の取得
func getArgs(lex *Lex) []Expr {
e := make([]Expr, 0)
if lex.Token != '(' {
panic(fmt.Errorf("'(' expected"))
}
lex.getToken()
if lex.Token == ')' {
lex.getToken()
return e
}
for {
e = append(e, expression(lex))
switch lex.Token {
case ')':
lex.getToken()
return e
case ',':
lex.getToken()
default:
panic(fmt.Errorf("unexpected token in argument list"))
}
}
}
// 因子
func factor(lex *Lex) Expr {
switch lex.Token {
case '(':
lex.getToken()
e := expression(lex)
if lex.Token != ')' {
panic(fmt.Errorf("')' expected"))
}
lex.getToken()
return e
case '+':
lex.getToken()
return newOp1('+', factor(lex))
case '-':
lex.getToken()
return newOp1('-', factor(lex))
case scanner.Int, scanner.Float:
var n float64
fmt.Sscan(lex.TokenText(), &n)
lex.getToken()
return Value(n)
case scanner.Ident:
name := lex.TokenText()
lex.getToken()
if name == "quit" {
panic(name)
}
v, ok := funcTable[name]
if ok {
xs := getArgs(lex)
if len(xs) != v.Argc() {
panic(fmt.Errorf("wrong number of arguments: %v", name))
}
return newApp(v, xs)
} else {
return Variable(name)
}
default:
panic(fmt.Errorf("unexpected token: %v", lex.TokenText()))
}
}
// 項
func term(lex *Lex) Expr {
e := factor(lex)
for {
switch lex.Token {
case '*':
lex.getToken()
e = newOp2('*', e, factor(lex))
case '/':
lex.getToken()
e = newOp2('/', e, factor(lex))
default:
return e
}
}
}
// 式
func expr1(lex *Lex) Expr {
e := term(lex)
for {
switch lex.Token {
case '+':
lex.getToken()
e = newOp2('+', e, term(lex))
case '-':
lex.getToken()
e = newOp2('-', e, term(lex))
default:
return e
}
}
}
func expression(lex *Lex) Expr {
e := expr1(lex)
if lex.Token == '=' {
v, ok := e.(Variable)
if ok {
lex.getToken()
return newAgn(v, expression(lex))
} else {
panic(fmt.Errorf("invalid assign form"))
}
}
return e
}
// 式の入力と評価
func toplevel(lex *Lex) (r bool) {
r = false
defer func(){
err := recover()
if err != nil {
mes, ok := err.(string)
if ok && mes == "quit" {
r = true
} else {
fmt.Fprintln(os.Stderr, err)
for lex.Token != ';' {
lex.getToken()
}
}
}
}()
for {
fmt.Print("Calc> ")
lex.getToken()
e := expression(lex)
if lex.Token != ';' {
panic(fmt.Errorf("invalid expression"))
} else {
fmt.Println(e.Eval())
}
}
return r
}
func main() {
var lex Lex
lex.Init(os.Stdin)
initFunc()
for {
if toplevel(&lex) { break }
}
}
// 二分探索の改正
// 二分探索
def bsearch(x, v, low, high)
let
result = 0
in
while low <= high and result == 0 do
let
mid = (low + high) / 2
in
if v[mid] == x then
begin result = 1,high = -1 end
else
if v[mid] < x then
low = mid + 1
else
high = mid - 1
end
end
end
end,
result
end
end
def binarySearch(x, v)
bsearch(x, v, 0, len(v) - 1)
end
登録:
投稿 (Atom)