
è¯ãäžæ¥ã
ãã®èšäºã§ã¯ãVisual Studio 2010ã®äž»èŠãªé©æ°ã®1ã€ãã€ãŸã颿°åããã°ã©ãã³ã°èšèªFïŒã確èªããŸãã
FïŒã®æ§æãšå¯èœæ§ããç§ãã¡ãçºæããããã°ã©ãã³ã°èšèªçšã«ç¬èªã®ã€ã³ã¿ãŒããªã¿ãŒãäœæããäŸã䜿çšããŠæ€èšããŸãïŒçµå±ãäŸã«ã€ããŠäœãã話ãããšã¯åžžã«è峿·±ãã§ãïŒã
解決ããããšããŠããã¿ã¹ã¯ãã€ãŸãããã°ã©ãã³ã°èšèªã®æ§æã«ã€ããŠèª¬æããŸããããã¯éåžžã«åçŽã§ãèŠãããã®ã§ãã
function Summ(a,b,c)
{
val d = a+b+c;
print d;
return d;
}
function MyEvaluations(a,b,c)
{
val in = Summ(a,b,1);
val out = Summ(b,c,1);
val d = in*out;
return d;
}
function Program()
{
print(MyEvaluations(1,2,3));
}
ãã®ããããã©ã¡ãŒã¿ãŒã®åãæž¡ããšæ»ãå€ãå°å·ãç®è¡æŒç®ãããŒã«ã«å€æ°ãæã€é¢æ°ããµããŒãããŠããŸãã
ããã®å®è£
ãéå§ããŸãããã®ãã
ããããã远å ã®FïŒPower Packãã€ã³ã¹ããŒã«ããå¿
èŠããã
ãŸãèªåœ
次ã«ãFïŒParsed Language Starterãªã³ã©ã€ã³ãã³ãã¬ãŒãããæ°ããFïŒãããžã§ã¯ããäœæããlexer.fslãé€ããã¹ãŠã®ãã¡ã€ã«ãã¯ãªã¢ããŸãã
ãã®ãã¡ã€ã«ã®å
容ãåŠçããããã«ããŸãèšèªã骚ããšã«åæããŸãããã ãããŒã¯ã³ããšããèšèã¯ãããã°ã©ãã³ã°èšèªãæ§æããæå°éã®ã¬ã³ã¬ãæå³ããŸãã
ããŒã¯ã³ã«ã¯ãããŒã¯ãŒãããã©ã±ãããã³ã³ããååãäžè¬ã«ãããã°ã©ã ã®ãœãŒã¹ã³ãŒããæ§æãããã¹ãŠã®ãã®ãå«ãŸããŸãã ããŒã¯ã³ã®ã¬ãã«ã§ã¯ã颿°ãä»ã®
è«çãŠãããã¯ãããŸããã
lexer.fslãã¡ã€ã«ãéã
FïŒã§ã¯ãããŒã¯ãŒãã¢ãžã¥ãŒã«ã¯åå空éã«é¡äŒŒããŠãããusingããŒã¯ãŒãã¯ãªãŒãã³ããŒã¯ãŒãã§ãããããã£ãŠãæåã«èšè¿°ããããšã¯ãäœæ¥é åãæ±ºå®ããããšã§ãã
{
module Lexer
open System
open Parser
open Microsoft.FSharp.Text.Lexing
let lexeme lexbuf =
LexBuffer<char>.LexemeString lexbuf
}
let digit = [ '0' - '9' ]
let whitespace = [ ' ' '\t' ]
let newline = ( '\n' | '\r' '\n' )
let symbol = [ 'a' - 'z''A' - 'Z' ]
FïŒã®å€æ°ã¯letããŒã¯ãŒãã䜿çšããŠå®£èšãããŸãããŸããããã§æ£èŠè¡šçŸã䜿çšã§ããŸãã
ãã®ãããè¡ã®äžã®ãã¹ãŠã®ã³ãŒããåé€ããŸã
rule tokenize = parse
ããã¯ãµãŒãã¹ããŒã«ãŒã§ãããèšèªã®èª¬æãäžã«è¡šç€ºãããããšã瀺ããæ¬¡ã®ã³ãŒããæ¿å
¥ããŸãã
| whitespace { tokenize lexbuf }
| newline { tokenize lexbuf }
// Operators
| "+" { PLUS }
| "-" { MINUS }
| "*" { MULTIPLE }
| "/" { DIVIDE }
| "=" { EQUALS }
// Misc
| "(" { LPAREN }
| ")" { RPAREN }
| "," { COMMA }
| ";" { ENDOFLINE }
| "{" { BEGIN }
| "}" { END }
// Keywords
| "function" { FUNCTIONKW }
| "return" { RETURN }
| "var" { VARIABLE }
ãã®ãã¡ã€ã«ã¯è¿œå ã®PowerPackã©ã€ãã©ãªããŒã«ã«ãã£ãŠåŠçãããããããã®ãã¡ã€ã«èªäœã®FïŒã³ãŒãã¯äžæ¬åŒ§ã®æåã®ãããã¯ã«å²ãŸããŠããŸãã
ãããæãç°¡åãªéšåã§ããããã§ã¯ãèšèªã«ååšããæåå宿°ãŸãã¯æ£èŠè¡šçŸãèšè¿°ããã ãã§ãç®è¡æŒç®åãè§ãã£ãã3ã€ã®ããŒã¯ãŒããã³ã³ããã»ãã³ãã³ã®ããã€ãããããŸãã
次ã«ãæ£èŠè¡šçŸã䜿çšããŠãã³ãŒããã倿°/颿°ã®æ°ãšååããåŒãåºããããã«ã€ã³ã¿ãŒããªã¿ãŒããã¬ãŒãã³ã°ããŸãã å®éããã®æ®µéã§ããã¬ãŒã³ããã¹ãã³ãŒããæ¬¡ã®ãããªãªããžã§ã¯ãã®ã·ãŒã±ã³ã¹ã«å€æããŸããã
FUNCTIONKEYWORD NAME LPAREN NAME COMMA NAME COMMA NAME RPAREN
BEGIN
VARIABLE NAME EQUALS NAME PLUS NAME PLUS NAME ENDOFLINE
âŠ..
åãªããžã§ã¯ãã«ã¯ç¬èªã®ã¿ã€ãããããäžèšã®äŸã§ç€ºãããŠããŸãã
ãã ããDECIMALããã³NAMEãªããžã§ã¯ãã«ãå€ãå¿
èŠã§ãã
ãããè¡ãã«ã¯ã次ã®è¡ãèšè¿°ããŸãã
| digit+( '.' digit+)? { DECIMAL(Double.Parse(lexeme lexbuf)) }
| symbol+ { VARNAME(String.Copy(lexeme lexbuf)) }
| eof { EOF }
ããã¯ã³ã³ã¹ãã©ã¯ã¿ãŒåŒã³åºããšããŠè§£éã§ããŸãã äžæ¬åŒ§ã§å²ãŸããŠããã®ã¯ãããŒã¿åã ãã§ãã åŠçåŸãããã°ã©ã ããã¹ãã¯ãããã®ã¿ã€ãã®ãªããžã§ã¯ãã®ã·ãŒã±ã³ã¹ã«ãªããŸãã
eof-è§£æãããããã¹ãã®çµãããç¥ããããµãŒãã¹ããŒã¯ã³
è§£æ
ããŒã¿åãã©ãããæ¥ãã®ãããããŠNAMEãæååã³ã³ãã³ããæã¡ãDECIMALãæ°å€ã§ããçç±ãå°ãæç¢ºã«ããããã«ãParser.fsyãã¡ã€ã«ãéããæ¬¡ã®ã³ãŒãã貌ãä»ããŸãã
%{
open ParserLibrary
open System
%}
%start start
%token <Double> DECIMAL
%token PLUS MINUS MULTIPLE DIVIDE
%token LPAREN RPAREN
%token FUNCTIONKW RETURN VARIABLE
%token BEGIN END
%token EQUALS
%token <String> VARNAME
%token ENDOFLINE
%token COMMA
%token EOF
%type <WholeProgram> start
%%
ããã«ãã¹ãŠã®ããŒã¿åã瀺ãããŠããŸããåã«å€ãå¿
èŠãªå Žåããã®å€ã®åã¯å±±æ¬åŒ§ã§å²ãŸããŠããŸãã
éå§ã¯ããããããææ³å
¬çãã§ããããã¯ãã³ãŒããè§£éãããšãã«ãåéãããããšãããã®ã§ãã
ææ³ã¯æ¬¡ã®åœ¢åŒã§æžãããŠããŸãã
: | | | ⊠| âŠ
æåã®è¡ã¯æ¬¡ã®ããã«ãªããŸãã
start: | WholeProgram
ããã¯ãåæã®ç®æšããããã°ã©ã å
šäœããååŸããããšã§ããããšã瀺åããŠããŸã
ããèŠããšãããã°ã©ã å
šäœãã¯é¢æ°ã®ãªã¹ãã«ãããŸãã
ãããã£ãŠããã®äºå®ãæžããŸãã
WholeProgram:
| FunctionDescription
| WholeProgram FunctionDescription
ãã®èšé²åœ¢åŒã§ãªã¹ãã圢æãããšããããªãçãã圢åŒã«æ³šç®ãã䟡å€ããããŸããå®éãåèŠçŽ ã®ãã³ã³ããŒãã³ããã®æ°ã¯åºå®ããå¿
èŠããããŸããç§ãã¡ã®èšèªã§å¯èœãªæ©èœã®æ°ãå¶éããªãããã«ããã®ãããªããªãã¯ãéžã³ãŸãã ã·ã¹ãã ãæåã®é¢æ°ãèŠã€ãããš-ããããWholeProgramãªããžã§ã¯ããäœæãã2çªç®ã®é¢æ°ãèŠããš-é£ã«WholeProgramïŒæåã®é¢æ°ããïŒãšFunctionDescriptionïŒ2çªç®ã®é¢æ°ïŒããããã·ã¹ãã ã¯ãããã®ãªããžã§ã¯ãã®äž¡æ¹ãæ°ããWholeProgramã«æãããã¿ãå¶éãåé€ããŸãããã°ã©ã ããã¹ãå
ã®é¢æ°ã®ç·æ°ã
ææ³ã説æãããšã次ã®å³ãåŸãããŸãã

颿°ãäœã§ããããèšè¿°ããŸãïŒ
FunctionDescription:
| FunctionKeyWord FunctionTitle Begin End
| FunctionKeyWord FunctionTitle Begin OperatorsList End
衚çŸã®2çªç®ã®ããŒãžã§ã³ã®ã¿ã«å¶éããããšãã§ããŸããããã®å Žåãã³ãŒããããããããã«ã空ã®é¢æ°ã¯ã€ã³ã¿ãŒããªã¿ãŒã§ãšã©ãŒã«ãªããŸãããã®é¢æ°ã¯ãããŒã¯ãŒããèŠåºããäžæ¬åŒ§ãããã³å Žåã«ãã£ãŠã¯é¢æ°å
ã®æŒç®åã®ã»ããã§æ§æãããŸã-ãã®æ¬äœ
颿°ããããŒã¯ããã®ååãæ¬åŒ§ãããã³å Žåã«ãã£ãŠã¯ãã©ã¡ãŒã¿ãŒã®ãªã¹ãã§æ§æãããŸãã
FunctionTitle:
| VarName LParen RParen //
| VarName LParen VarName RParen // . ,
| VarName LParen VarName AdditionParametersList RParen //
AdditionParametersListããã³OperatorsListãªããžã§ã¯ãã¯ãªã¹ãã§ãããããWholeProgramãšåæ§ã«å®çŸ©ãããŸãã
OperatorsList:
| Operator
| OperatorsList Operator
AdditionParametersList:
| Comma VarName
| AdditionParametersList Comma VarName
æŒç®åã¯ã颿°ã®æ¬äœå
ã®ããã°ã©ã ã®1è¡ã§ã;èšèªã«ã¯2ã€ã®ãªãã·ã§ã³ããããŸãã
Operator:
| VaribaleKeyWord VarName Equals Expression EndOfLine
| ReturnKeyWord Expression EndOfLine
ããšãã°ã次ã®è¡ã«å¯Ÿå¿ããŸãã
val d = in*out;
return d;
æåã«ãä¹ç®ãšé€ç®ãå ç®ãšæžç®ãããåªå
é äœã®é«ãæŒç®ã§ããããšãèæ
®ããŠã4ã€ã®ç®è¡æŒç®ãå®çŸ©ããŸããã
Expression:
| Expression PLUS HighExpression
| Expression MINUS HighExpression
| HighExpression // "Operator"' Expresson, "" .
HighExpression:
| HighExpression MULTIPLY Operand
| HighExpression DIVIDE Operand
| Operand // , - .
ãã®åé¢ã«ãããåŒ2 + 2 * 2ãExpression Plus HighExpressionãšããŠè§£æããHighExpressionãå¥ã®ãµãããªãŒã«å±éã§ããŸãïŒExpression PlusïŒHighExpression MULTIPLY OperandïŒãæäœã®åªå
åºŠãæ£ããåŠçããŸãã
äžäœã¬ãã«ã§ã¯ããªãã©ã³ãã¯ãæ°å€ãæ¢åã®å€æ°ã®ååã颿°ã®ååããŸãã¯æ¬åŒ§å
ã®åŒïŒå¿
èŠãªå ŽåïŒã®ããããã§ãã
Operand:
| DECIMAL
| VarName
| FunctionTitle
| LParen Expression RParen // Expression , .
FïŒïŒçŸåšã¯çŽç²ãªåœ¢åŒïŒã«æ»ãããã¿ãŒã³ãããã³ã°ã䜿çšããã³ã³ã¹ãã©ã¯ã¿ãŒãªã©ã®å¯èœæ§ãèããŠã¿ãŸããããã€ãŸãã䜿çšããããŒã¿åã説æããŸãã
namespace ParserLibrary
open System
type Operator =
| VarOperator of string * Expression
| ReturnOperator of Expression
and Operand =
| DECIMALOP of Double
| SUBEXPROP of Expression
| VARNAMEOP of String
| FUNCOP of FunctionTitle
and HighExpression =
| MULTIPLY of HighExpression * Operand
| DIVIDEOP of HighExpression * Operand
| VAR of Operand
and Expression =
| SUMM of Expression * HighExpression
| SUB of Expression * HighExpression
| HighExpression of HighExpression
and FunctionTitle = String * List<String>
and FunctionDescription = FunctionTitle * OperatorsList
and OperatorsList = List<Operator>
and AdditionParamsList = List<String>
and WholeProgram = List<FunctionDescription>
å®éã9ã€ã®ãªããžã§ã¯ãã宣èšããŸãããåãªããžã§ã¯ãã«ã¯ãç°ãªããã©ã¡ãŒã¿ãŒãæã€è€æ°ã®
ååä»ãã³ã³ã¹ãã©ã¯ã¿ãŒããããŸãïŒå®éããã®ãããªã³ã³ã¹ãã©ã¯ã¿ãŒã®ã»ããã¯C ++ã®ãŠããªã³ã«äŒŒãŠããŸãïŒ
ãã®ã³ã³ããã¹ãã§ã®ã¢ã¹ã¿ãªã¹ã¯ã*ãã¯ä¹ç®ã§ã¯ãªãããã©ã¡ãŒã¿åºåãæåãã€ãŸã ã¿ã€ã
Operatorã® VarOperatorãšããååã®ã³ã³ã¹ãã©ã¯ã¿ãŒã¯ãæååïŒstringïŒãšåŒïŒexpressionïŒãåãåããŸã
ã€ã³ã¿ããªã¿ãäœæããæåã®éšåãå®äºããããã«å¿
èŠãªããšã¯ããããã®ããŒã¿åãParser.fsyãã¡ã€ã«ã«æ¥ç¶ããããšã§ãããã®ãããåæ¡ä»¶ã®æšªã«ããäžæ¬åŒ§ã§å¯Ÿå¿ããã³ã³ã¹ãã©ã¯ã¿ãèšè¿°ããŸã
次ã®ããã«ãªããŸãã
start: WholeProgram { $1 }
WholeProgram:
| FunctionDescription { $1 :: [] }
| WholeProgram FunctionDescription { $1 @ ($2 :: []) }
FunctionTitle:
| VARNAME LPAREN RPAREN { $1, [] }
| VARNAME LPAREN VARNAME RPAREN { $1, $3 :: [] }
| VARNAME LPAREN VARNAME AdditionParamsList RPAREN { $1, $3 :: $4 }
AdditionParamsList:
| COMMA VARNAME { $2 :: [] }
| AdditionParamsList COMMA VARNAME { $1 @ ($3 :: []) }
OperatorsList:
| Operator { $1 :: [] }
| OperatorsList Operator { $1 @ ($2 :: []) }
FunctionDescription:
| FUNCTIONKW FunctionTitle BEGIN END { $2, [] }
| FUNCTIONKW FunctionTitle BEGIN OperatorsList END { $2, $4 }
Operator:
| VARIABLE VARNAME EQUALS Expression ENDOFLINE { VarOperator($2, $4) }
| RETURN Expression ENDOFLINE { ReturnOperator($2) }
Expression:
| Expression PLUS HighExpression { SUMM($1, $3) }
| Expression MINUS HighExpression { SUB($1, $3) }
| HighExpression { HighExpression $1 }
HighExpression:
| HighExpression MULTIPLE Operand { MULTIPLY($1, $3) }
| HighExpression DIVIDE Operand { DIVIDEOP($1, $3) }
| Operand { VAR $1 }
Operand:
| DECIMAL { DECIMALOP($1) }
| VARNAME { VARNAMEOP($1) }
| FunctionTitle { FUNCOP($1) }
| LPAREN Expression RPAREN { SUBEXPROP($2) }
$ 1ã$ 2ãªã© æ¡ä»¶å
ã®å€æ°ã®æ°ã§ã
ãã®ã³ãŒããäŸãšããŠäœ¿çšããŠãFïŒã®ãã1ã€ã®åªããæ©èœã§ãããªã¹ãã®æäœã玹ä»ããŸãã
åŒA :: Bã¯ãèŠçŽ Aã远å ãããªã¹ãBã«åºã¥ããŠæ°ãããªã¹ããäœæããŠè¿ãããšãæå³ããŸã
[]-空ã®ãªã¹ã
ãŸããã³ãŒãã§ãªã¹ããçŽæ¥ãŸãã¯ç¯å²ããæå®ããããšãã§ããŸããäŸïŒ
[1,2,3,4,5]ãŸãã¯[1..5]
ãã®å Žåã100 :: [1..5]ã¯æ¬¡ã®ãããªãªã¹ããè¿ããŸãïŒ[100,1,2,3,4,5]
@æŒç®å-2ã€ã®æ¢åã®ãªã¹ãã®åéåããæ°ãããªã¹ããäœæããŸãã
äŸïŒ[1..5] @ [6..10]ã¯[1..10]ãè¿ããŸã
ãã³ãã¬ãŒãã«ããéžæã®å Žå-ä»»æã®ã¿ãã«ïŒFunctionDescriptionãOperatorsListãªã©ïŒãšå矩ã§ããåãåã«å¯ŸããŠãååä»ãã³ã³ã¹ãã©ã¯ã¿ãŒãæå®ããããšã«æ³šæããŠãã ãã-宣èšããé åºã§ãã©ã¡ãŒã¿ãŒããªã¹ãããã ãã§ãã¿ãã«ã
ãããã£ãŠããããFïŒããã¬ãŒã³ããã¹ãããè§£æããªãŒãäœæããããã«å¿
èŠãªãã¹ãŠã§ãã2çªç®ã®éšåã¯è§£éã§ãã
Program.fsãã¡ã€ã«ãéãã䜿çšããåå空éã«å¯ŸããŠæžã蟌ã¿ãéããŸãã
open System
open Microsoft.FSharp.Text.Lexing
open System.Collections.Generic;
open ParserLibrary
open Lexer
open Parser
è§£é
ããã«ãè§£éã®ããã«ã颿°ã®ãªã¹ãïŒãŸãã¯ãããè¯ãèŸæžïŒãå颿°ã®ååä»ãã¹ã¿ãã¯ïŒå€æ°åã®ç«¶åããªãããã«ïŒãããã³çŸåšå®è¡ãããŠãã颿°ã®ååãå¿
èŠã§ãã
ãããè¡ãã«ã¯ããã§ã«ããªãã¿ã®ããŒã¯ãŒãletã䜿çšããŠå€æ°ã宣èšããŸãã
let stack = Dictionary<String, Dictionary<String,Double>>()
let functionsList = Dictionary<String, FunctionDescription>()
let mutable currentFunctionName = "Program" ;
å€å
žçãªé¢æ°åããã°ã©ãã³ã°ã§ã¯ããã¹ãŠã®ãªããžã§ã¯ãã¯äžå€ã§ããããã¯ããªã¹ããæäœããäŸã§èŠãããšãã§ããŸãããªã¹ãã«ã¢ã€ãã ã远å ãã代ããã«ãæ¢åã®ãã®ã«åºã¥ããŠæ°ãããªããžã§ã¯ããäœæããŸãã ããã«ãããããã°ã©ã ãã·ãŒã ã¬ã¹ã«äžŠååã§ããŸãã è€éãªåæãèšè¿°ããå¿
èŠã¯ãããŸããã
FïŒã¯é¢æ°åèšèªã§ããã.NETã©ã€ãã©ãªå
šäœãå®å
šã«ãµããŒãããŠãããããå¯å€ãªããžã§ã¯ããæäœã§ããŸãã ãã®å ŽåãããŒã¿ã®å®å
šãªã³ããŒã¯è¡ãããããªããžã§ã¯ããžã®åç
§ã®ã¿ãã³ããŒãããŸããããã«ãããå¿
èŠã«å¿ããŠæžãèŸŒã¿æã®ã³ããŒã®äžçš®ã§ããããŒã¿ãçŸãã䞊ååããæ©èœãæãªãããšãªããé床ã®åŠ¥åãéæã§ããŸãã
ã ãããè§£éã«å
¥ããŸãããïŒ
åŒãè§£æããããšããå§ããŸããã
ãã³ãã¬ãŒãã«ããéžæã§é¢æ°ã宣èšããrec-ããŒã¯ãŒããEvaluateExpression-ååãexpression-ãã©ã¡ãŒã¿ãŒãèš±å¯ããŸãã
åã宣èšãããšãããã³ãã¬ãŒãã«ããéžæã§ã³ã³ã¹ãã©ã¯ã¿ãäœæãããšãã颿°ãå®è¡ãããã©ã³ããéžæãããšãã«åããã³ãã¬ãŒãã䜿çšããããšãæãåºããŠãã ããã äŸïŒæž¡ããããã©ã¡ãŒã¿ãŒåŒãSUMMïŒåŒãhighExpressionïŒã³ã³ã¹ãã©ã¯ã¿ãŒã䜿çšããŠäœæãããå Žåã远å ãã©ã³ããªã©ãå®è¡ããŸãã
ãã®é¢æ°ã¯ã以åã«äœæãããã³ã³ã¹ãã©ã¯ã¿ãŒãå®éã«ç¹°ãè¿ããããããã«ç¹å®ã®ã¢ã¯ã·ã§ã³ãå²ãåœãŠãããšã«æ°ä»ããããããŸãã
let rec evaluateExpression expression =
match expression with
| SUMM (expr, hexpr) -> (evaluateExpression expr) + (evaluateHighExpression hexpr)
| SUB (expr, hexpr) -> (evaluateExpression expr) - (evaluateHighExpression hexpr)
| HighExpression hexpr -> evaluateHighExpression hexpr
and evaluateHighExpression highExpression =
match highExpression with
| MULTIPLY (hexpr, oper) -> (evaluateHighExpression hexpr) * (EvaluateOperand oper)
| DIVIDEOP (hexpr, oper) -> (evaluateHighExpression hexpr) / (EvaluateOperand oper)
| VAR oper -> EvaluateOperand oper
and EvaluateOperand oper =
match oper with
| DECIMALOP x -> x
| VARNAMEOP x -> stack.Item(currentFunctionName).Item(x)
| FUNCOP x -> evaluateFunction x
| SUBEXPROP x -> evaluateExpression x
倿°ãšé¢æ°ã®ãµããŒããå°å
¥ããããããã®å Žåã®ãã³ãã©ãŒãäœæããå¿
èŠããããŸãã 倿°ã®å Žåããã¹ãŠã¯å€ããå°ãªããåçŽã§ããçŸåšã®é¢æ°ã®å€æ°ã®å€ãå«ãèŸæžã«è¡ãã倿°ã®ååã§å€ãååŸããŸãïŒVARNAMEOPã¯Stringåã«é¢é£ä»ããããŠããããšãæãåºããŠãã ããïŒ
颿°ãšã®æ¥è§Šã®å Žåã颿°ã®ããããŒã«åŸã£ãŠåŒã³åºãå
ã®é¢æ°ãããã©ã¡ãŒã¿ãŒãã³ããŒãããã®å®è¡ãéå§ããå¿
èŠããããŸãã
ãããè¡ãã«ã¯ã次ã®ã³ãŒãã远å ããŸãã
and evaluateFunction(f:FunctionTitle) =
let caller = currentFunctionName;
let newStack = Dictionary<String, Double>()
let realParams = functionsList.Item (f |> GetFunctionName) |> GetFormalParamsListDecription
let formalParams = GetFormalParamsListTitle(f)
ignore <| List.mapi2 ( fun i x y -> newStack.Add(x, stack.Item(caller).Item(y))) realParams formalParams
currentFunctionName <- GetFunctionName(f)
stack.Add(currentFunctionName, newStack)
let operatorsList = functionsList.Item(GetFunctionName f) |> GetOperatorsList
let result = RunFunction operatorsList
ignore <| stack.Remove(currentFunctionName)
currentFunctionName <- caller
result
//
ãããæ©èœã§ããããã³ãã¬ãŒããéžæããã®ã§ã¯ãªãããã銎æã¿ã®ãã圢åŒã§ãã
ãã€ãã©ã€ã³æŒç®åã|>ãã調ã¹ãŠã¿ãŸããããå®éãããã¯é¢æ°ãã§ãŒã³ãåŒã³åºãããçè§£ããããæ¹æ³ã§ãã以åã«OuterFunctionïŒInnerFunctionïŒValidateïŒdataïŒïŒïŒãèšè¿°ããå¿
èŠãããå Žåã¯ãFïŒã§ãã®ãã§ãŒã³ããå±éãã§ããŸãïŒdata |>æ€èšŒ|> InnerFunction |> OuterFunction
äž¡æ¹ã®ãšã³ããªã¯åãçµæã«ãªããŸãããã|>ãæŒç®åã䜿çšããå Žåã颿°ã¯å·Šããå³ã«é©çšãããŸããé·ããã§ãŒã³ã®å Žåã¯ãã䟿å©ã§ãã
ãããã®é¢æ°ã®ç¹åŸŽã¯ãæ»ãå€ãããšãã°é¢æ°ãæžãå¿
èŠããªãããšã§ãã
ãã¹ãïŒaïŒ= a * 10
* 10ãè¿ããŸãããããã¯éšåçã«äŸ¿å©ã§ãããã誀ã£ãŠãå€ãè¿ããªãããã«æ³šæããå¿
èŠããããŸãïŒãšããã§ãVSã¯ãã¹ãŠã®æå³ããªãæ»ãå€ã匷調ããŸãïŒãè¡ã®å
é ã§ãã¹ãŠç¡èŠããããšãè¿ããŸã-éãã€ãã©ã€ã³æŒç®åã<|ãã䜿çšããŸããã|>ããšåãããã«ãå察æ¹åã§ã®ã¿æ©èœãã颿°ã¯å³ããå·Šã«é©çšãããŸãã
åçŽãªå²ãåœãŠã®å Žåãå€ãè¿ãããªãããã«ãã=ãã®ä»£ããã«ã<-ãæŒç®åã䜿çšããŸã
è¡ãããã«è©³ããåæããŠã¿ãŸãããã
ignore <| List.mapi2 ( fun i x y -> newStack.Add(x, stack.Item(caller).Item(y))) realParams formalParams
Listã¯ã©ã¹ã«ã¯äžé£ã®mapi *ã¡ãœããïŒç°ãªãæ°ã®ãªã¹ãïŒãå«ãŸããŸãããããã®ã¡ãœããã®æ¬è³ªã¯ãè€æ°ã®ãªã¹ãïŒãã®å Žåã¯2ïŒã䞊è¡ããŠåŠçããäž¡æ¹ã®ãªã¹ãã®èŠçŽ çªå·ãšèŠçŽ èªäœãé·ããåæãšããŠãã³ãã©ãŒé¢æ°ã«æž¡ãããšã§ããªã¹ãã¯çããã§ãã mapi2ã¡ãœããã¯ã3ã€ã®ãã©ã¡ãŒã¿ãŒããã³ãã©ãŒé¢æ°ãããã³2ã€ã®åŠçæžã¿ãªã¹ããåãå
¥ããŸãã
ããšãã°ã次ã®ã³ãŒããå®è¡ããçµæãšããŠïŒ
let firstList = [1..5]
let secondList = [6..10]
ignore <| List.mapi2 ( fun i x y -> Console.WriteLine(10*x+y)) firstList secondList
çµæãåŸãããŸãïŒ16 27 38 49 60
颿°ãåŒã³åºããšããšèšèªã§èšè¿°ãããšãã¯ãæ¬åŒ§å
ã®ãã©ã¡ãŒã¿ãŒã®é åºãåãã§ãããããåŒã³åºããªã¹ããšé¢æ°å®£èšã®èŠçŽ ããã¢ã§åŠçããã ãã§ãã
funããŒã¯ãŒãã¯ããªã¹ããåŠçããããã«äœ¿çšããæ°ãã颿°ãå®çŸ©ããŸãïŒCïŒã§ã©ã ããšã®é¡äŒŒæ§ãæãããšãã§ããŸãïŒããã®é¢æ°ã¯3ã€ã®ãã©ã¡ãŒã¿ãŒãåããŸããiã¯äž¡æ¹ã®ãªã¹ãã®çŸåšã®èŠçŽ ã®çªå·ãxãšyã¯ããããæåãš2çªç®ã®ãªã¹ãã®èŠçŽ ã§ãã
ãããã£ãŠãããã§ã¯ãåŒã³åºãå
ã®é¢æ°ã®ã¹ã¿ãã¯ãã倿°ãæ°ããã¹ã¿ãã¯ã«ã³ããŒããŠããŸãã
ãã©ã¡ãŒã¿ãŒãæºåããåŸã颿°ãåŒã³åºããçµæãèšæ¶ããèŸæžïŒã¹ã¿ãã¯ïŒãåé€ããåŒã³åºãå
ã®é¢æ°ã®ååã埩å
ããŸãã
let result = RunFunction operatorsList
ignore <| stack.Remove(currentFunctionName)
currentFunctionName <- caller
result
ãªããªã returnã¯æžã蟌ãå¿
èŠã¯ãããŸãããå€ãè¿ãã«ã¯ãè¿ã倿°ã®ååãæžã蟌ãã ãã§ãã
次ã«ãrunFunctionã¡ãœãããäœæããŸãã
and RunFunction(o:OperatorsList) =
ignore <| List.map ( fun x -> EvaluateOperator x) o
stack.Item(currentFunctionName).Item( "return" )
List.mapã¡ãœããã¯ãªã¹ãã®ãã¹ãŠã®èŠçŽ ãå埩åŠçããçŸåšã®ã¹ã¿ãã¯ããçµæã®å€æ°ãè¿ãã ãã§ãã
and EvaluateOperator operator =
match operator with
| VarOperator (name, expr) -> stack.Item(currentFunctionName).Add(name, evaluateExpression expr)
| ReturnOperator expr -> stack.Item(currentFunctionName).Add( "return" , evaluateExpression expr)
ç§ãã¡ã®èšèªã«ã¯2çš®é¡ã®æŒç®åãããããŸãããããã¯å€æ°å®£èšãŸãã¯æ»ãå€ã®ããããã§ããã©ã¡ãã®å Žåãå€ãèšç®ããŠèŸæžïŒã¹ã¿ãã¯ïŒã«è¿œå ããæ»ãã®å Žåã¯èšèªã§ã®æ»ããããŒã¯ãŒãã§ãããå®å
šã«ã§ãããšããäºå®ã䜿çšããŸãæ¢ã«å®£èšãããŠãã倿°ãšã®ç«¶åãæããããšãªããç¬èªã®ç®çã§äœ¿çšããŠãã ããã
èšèªã§äºåå®çŸ©ãããããã€ãã®é¢æ°ã䜿çšãããããI / Oãå®è£
ããããã«ããã€ãã®ãã§ãã¯ã远å ããŸãã
and RunFunction(o:OperatorsList) =
if currentFunctionName.Equals "print" then
stack.Item(currentFunctionName).Add( "return" , 0.0)
Console.WriteLine(stack.Item(currentFunctionName).Item( "toPrint" ).ToString())
if currentFunctionName.Equals "get" then
Console.Write( "Input: " );
stack.Item(currentFunctionName).Add( "return" , Double.Parse(Console.ReadLine()))
if currentFunctionName.Equals "Program" then
stack.Item(currentFunctionName).Add( "return" , 1.0)
ignore <| List.map ( fun x -> EvaluateOperator x) o
stack.Item(currentFunctionName).Item( "return" )
颿°ã®ååã確èªããçµæã«å¿ããŠã倿°ã®å€ãåºåããããããŒããŒãããå€ãèªã¿åããŸãã
ã¡ã€ã³ã®returnã¡ãœããã«æžã蟌ãŸãªãããã«ãã¹ãã·ã£ã«ãå®çŸ©ããŸãã 颿°æ¬äœãå®è¡ãããåã§ã倿°ã
ç¹ã«ãifãããã¯ã®æ¬äœã匷調ããããã«ãFïŒã§éèŠãªã€ã³ãã³ãã䜿çšãããŸãã
æåŸã«è¡ãå¿
èŠãããã®ã¯ã䜿çšããŠããªã颿°ãç¹å®ããããŒãµãŒã䜿çšããã·ã§ã«ãäœæããããšã§ãã
let GetFunctionName f = match f with name, foo -> name
let GetFunctionNameDescription f = match f with t, foo -> GetFunctionName t
let GetFormalParamsListTitle t = match t with foo, paramerers -> paramerers
let GetFormalParamsListDecription f = match f with t, foo -> GetFormalParamsListTitle t
let GetOperatorsList f = match f with foo, o -> o
let GetTitle f = match f with t, too -> t
äžéšã®åã¯åã«å矩èªãšããŠå®£èšãããããã³ã³ã¹ãã©ã¯ã¿åããªãåèªã®åŸã«ããã¹ãŠã®ãã©ã¡ãŒã¿ãŒã®åæããããç¢å°ã®åŸã«é¢æ°æ¬äœããããŸãããã®å Žåãè¿ãããå¿
èŠã®ãã倿°ã®ååãæžã蟌ãã ãã§ãã
æ¬åŒ§ãªãã§é¢æ°åŒã³åºããèšè¿°ããããšãçããå ŽåãFïŒã䜿çšãããšã次ã®åœ¢åŒã§ã³ãŒããèšè¿°ã§ããŸãã
let GetFunctionName(f) = match f with name, foo -> name
let GetFunctionNameDescription(f) = match f with t, foo -> GetFunctionName(t)
let GetFormalParamsListTitle(t) = match t with foo, paramerers -> paramerers
let GetFormalParamsListDecription(f) = match f with t, foo -> GetFormalParamsListTitle(t)
let GetOperatorsList(f) = match f with foo, o -> o
let GetTitle(f) = match f with t, too -> t
ãããã®ãšã³ããªã¯å®å
šã«åçã§ãã
æåŸã®ä»äžã
ãããŠæåŸã«ãæåŸïŒ
printfn "H#"
let mutable source = "" ;
let rec readAndProcess() =
printf ":"
match Console.ReadLine() with
| "quit" -> ()
| "GO" ->
try
printfn "Lexing..."
let lexbuff = LexBuffer<char>.FromString(source)
printfn "Parsing..."
let program = Parser.start Lexer.tokenize lexbuff
ignore <| List.map ( fun x -> functionsList.Add(GetFunctionNameDescription(x),x)) program
functionsList.Add( "print" ,(( "print" , [ "toPrint" ]), []))
functionsList.Add( "get" ,(( "get" , []), []))
printfn "Running..."
ignore <| (functionsList.Item( "Program" ) |> GetTitle |> evaluateFunction)
with ex ->
printfn "Unhandled Exception: %s" ex.Message
readAndProcess()
| expr ->
source <- source + expr
readAndProcess()
readAndProcess()
è§£æãæåããå ŽåãããŒããŒãããå
¥åãããæååãè§£æããããšããæ°ãã颿°ãå®çŸ©ããŸã-åä¿¡ãããªã¹ãïŒããã°ã©ã ïŒãããã¹ãŠã®é¢æ°ãfunctionsList倿°ã«è¿œå ããŸãã
ããã°ã©ã ã®å
é ã§é¢æ°ãåŒã³åºãã«ã¯ããã¡ã€ã«ã®æ«å°Ÿã«ã€ã³ãã³ãããã«ååãæžãã ãã§ãã
èšèªã«ã¯2ã€ã®äºåå®çŸ©é¢æ°ïŒgetããã³printïŒãããããããããã远å ããŠãããProgramãšãã颿°ãå®è¡ããŸãã
ãã®äŸã§æåŸã«èª¬æã§ããã®ã¯ãäžèŽã«ãã£ãŠã³ã³ã¹ãã©ã¯ã¿ãŒãå®çŸ©ããªãã£ããªããžã§ã¯ããæ§ç¯ããè峿·±ãæ¹æ³ã§ã
and FunctionTitle = String * List<String>
and FunctionDescription = FunctionTitle * OperatorsList
and OperatorsList = List<Operator>
and AdditionParamsList = List<String>
and WholeProgram = List<FunctionDescription>
FunctionTitleãªããžã§ã¯ããå¿
èŠãªå Žåããããäœæããã«ã¯ããã®ãã©ã¡ãŒã¿ãŒïŒStringããã³<ListString>ïŒãæ¬åŒ§ã§å²ãã ãã§ååã§ããããŒã¿åãæå®ããå¿
èŠã¯ãããŸããã
( "print" ,(( "print" , [ "toPrint" ]), []))
æã¡äžã
ããŠãã€ã³ã¿ããªã¿ãå®è¡ããŸãããïŒ

EnterããŒãæŒããšã倿°ã®å€ãå
¥åããããã³ããã衚瀺ãããŸãã

ãããŠãã®åŸïŒ

ãŸããããã°ã©ã ã¯æ¬åœã«åäœããŸãã
ãã€ããªãå«ããœãŒã¹ã³ãŒãã¯
ãã¡ãããããŠã³ããŒãã§ã
ãŸã ã
FïŒã®ã³ãŒããããäžåºŠèŠãŠã¿ããšãããããããšãç°¡åã«èª¬æããæå°éã®ãã®ãæžããããšãããããŸããç¬èªã®ã€ã³ã¿ãŒããªã¿ãŒãäœæããŠãã200è¡ã®ã³ãŒãã«åããããšãã§ããŸã.FïŒã䜿çšãããšãæ¥åžžçãªäœæ¥ãåãé€ãããšãã§ããŸã質åãwhatãã«ã¯çããªããã質åãhowãã«ã¯çããã³ãŒãã ãã¡ãããæåã¯ãã®èšèªã§ã®ããã°ã©ãã³ã°ã¯é£ããããã«èŠããŸãããã¡ã³ããã³ã¹ã容æãªæè»ãªã³ãŒããäœæã§ãããããå Žåã«ãã£ãŠã¯äŸ¡å€ããããŸãã
ãæž
èŽããããšãããããŸããã